diff --git a/Scripts/gen_sram_wrap/area_and_timing.txt b/Scripts/gen_sram_wrap/area_and_timing.txt index 5d524a4..3ad22a4 100644 --- a/Scripts/gen_sram_wrap/area_and_timing.txt +++ b/Scripts/gen_sram_wrap/area_and_timing.txt @@ -1,4 +1,4 @@ -======== ts1n12ffcllulvta1024x133_ssgnp0p72v125c.ds ========== +[DS]======== ts1n12ffcllulvta1024x133_ssgnp0p72v125c.ds ========== [Area Info] 1. Area Pre-shrink (dimensions in GDS database) @@ -8,7 +8,6 @@ Width(um) Height(um) Area(um²) 2.1 Timing Protocol (Refer to the waveforms in the databook) xxxxxxxxxxxxxxxxxx - [Timing Info] The following values are based on 1st point of LUT (Look Up Table) in NLDM liberty file @@ -25,6 +24,7 @@ tas 0.0927 A setup before CLK rising tah 0.0939 A hold after CLK rising tws 0.1108 WEB setup before CLK rising tbwh 0.0860 WEB hold after CLK rising + Error: tcyc OVER (0.9469ns > 0.8ns) [Conclusion] @@ -32,3 +32,8 @@ Area: 19006.4743 tcyc: 0.9469 tcd: 0.5055 ================================================================================ + + +[Summary] +== 1024x133 == +Area: 19006.4743 tcyc: 0.9469 tcd: 0.5055 \ No newline at end of file diff --git a/Scripts/gen_sram_wrap/get_ds_info.py b/Scripts/gen_sram_wrap/get_ds_info.py index 4d30dc7..293699b 100644 --- a/Scripts/gen_sram_wrap/get_ds_info.py +++ b/Scripts/gen_sram_wrap/get_ds_info.py @@ -1,6 +1,8 @@ import os import glob +import re +# exact infos from the files def extract_info(file_path): """提取关键信息""" area_info = [] @@ -73,6 +75,7 @@ def extract_info(file_path): return area_info, sram_timing, error_msgs, conclusion +# write info into files def write_info(): output = [] @@ -83,23 +86,60 @@ def write_info(): print(f"Processing: {ds_file}") area, timing, error_msgs, conclusion = extract_info(ds_file) - output.append(f"======== {os.path.basename(ds_file)} ==========\n") + output.append(f"[DS]======== {os.path.basename(ds_file)} ==========\n") output.append("[Area Info]\n") output.extend(area) output.append("[Timing Info]\n") output.extend(timing) + output.append("\n") + output.append(conclusion + "\n") if error_msgs: output.append("\n") print (f"Errors found in {ds_file}: {error_msgs}") output.extend([msg + "\n" for msg in error_msgs]) - output.append("\n") - output.append(conclusion + "\n") output.append("\n" + "="*80 + "\n") + # Finally output.append("\n") # 写入结果文件 with open('area_and_timing.txt', 'w') as f: f.writelines(output) +# parse the area_and_timig.txt file +def parse_summary(): + spec_dict = {} + processed_ds = set() # 新增:用于跟踪已处理的DS文件 + + with open('area_and_timing.txt', 'r') as f: + current_spec = None + current_ds = None + for line in f: + if line.startswith('[DS]'): + ds_name = line.split('========')[1].strip().split()[0] + if match := re.search(r'(\d+x\d+)', ds_name): + current_spec = match.group(1) + current_ds = ds_name + else: + current_spec = None + current_ds = None + + elif line.startswith('Area:'): + if current_spec and current_ds: + # 新增去重判断 + if current_ds not in processed_ds: + new_line = f"{line.strip()} From {current_ds}" + spec_dict.setdefault(current_spec, []).append(new_line) + processed_ds.add(current_ds) # 记录已处理文件 + + # ... 保持后续写入代码不变 ... + + # 追加汇总信息到文件 + with open('area_and_timing.txt', 'a') as f: + f.write("\n\n[Summary]") + for spec, values in spec_dict.items(): + f.write(f"\n== {spec} ==\n") + f.write('\n'.join(values)) + if __name__ == "__main__": write_info() + parse_summary() # 新增汇总解析 diff --git a/rtl/eth_mac/apb2axi.md b/rtl/eth_mac/apb2axi.md new file mode 100644 index 0000000..ddd9feb --- /dev/null +++ b/rtl/eth_mac/apb2axi.md @@ -0,0 +1,107 @@ +@[TOC](apb2axi DS文档) + +# 1 功能概述 +本设计模块是面向eth MAC CSR的AXI接口,设计apb2axi_bridge来进行给MAC CSR下发配置,考虑该模块具有一般通用性,可作为后续的通用性; +## 1.1 MAC IP CSR +1. 统一使用AXI总线管理控制信号和状态反馈 +2. 内置事务超时机制和死锁预防电路 +3. 集成中断仲裁器,多中断源合并为单输出 +4. 各功能通道寄存器采用线性地址映射 +5. 写1清除(Write-1-to-Clear)中断标志位 +6. 每个中断源有独立使能寄存器 +7. 基于功能通道的中断分组机制 + +# 2 接口列表及相关时序 +## 2.1 APB +apb相关接口应该是为了保持统一而使用32bit(待确认,因为脚本是支持生成64bit的),apb相关接口时序如下: +信号包括:PCLK, PRESETn, PSEL, PENABLE, PADDR, PWRITE, PWDATA, PRDATA, PREADY, PSLVERR。 +传输分为两个阶段:Setup阶段(PSEL=1,PENABLE=0)和Access阶段(PSEL=1,PENABLE=1)。当PREADY=1时,传输完成。 + + + +## 2.2 AXI +### 2.2.1 AXI拓扑结构() +64bit Data; +链式设备传递: +![alt text](image.png) + +![alt text](image-1.png) + +担心是否会在某一个串联的slave挂死--内置超时机制; +伪代码如下: +```python +def handle_transaction(addr): + if (MY_BASE_ADDR <= addr <= MY_END_ADDR): # 地址匹配本模块 + process_locally() # 本地处理 + return TERMINATED # 终止传递 + else: + forward_to_next() # 转发至下一级 + return FORWARDED +``` + +### 2.2.2 接口时序 +AXI的读写Single接口时序: +![alt text](image-2.png) + +![alt text](image-3.png) + +### 2.2.3 AXI features +支持功能如下: +1.基本接口规范:64位总线宽度、支持burst; +2.地址操作:固定地址(同一地址连续写入--填充缓冲区)、递增地址突发(地址自动递增的连续传输--内存拷贝); +3.特殊访问类型;支持非64位对齐的内存操作;支持32bit窄访问; + +不支持功能: +1.不支持非对齐访问下或窄访问下或回环下的突发操作; +2.保护访问:不支持特权内存级保护机制; +3.不支持原子读写; +4.严格执行顺序执行、不支持乱序处理; +5.不支持8位/16位窄访问; + +## 2.3 bridge接口时序 +该bridge转换接口 +### 2.3.1 bridge接口写时序 +接口写时序如下所示: +![alt text](image-7.png) + +### 2.3.2 bridge接口读时序 +接口读时序如下所示: +![alt text](image-9.png) + +# 3 模块结构图 + +# 4 详细设计 +在这里不支持burst和outsanding,每次只处理传输一个APB,因此其转换为AXI4的单个传输(读或写); +寄存器位宽是64bit;相邻寄存器间隔是8; +## 4.1 读写操作 +### 4.1.1 写操作(32-->64) +APB发起写:设置PADDR, PWDATA, PWRITE=1, PSEL=1,紧接着PENABLE=1。 +桥接模块需要将此次写转换到AXI4的写地址通道和写数据通道。 +1.先发送写地址(AWVALID=1,等待AWREADY=1); 同时(或之后)发送写数据(WVALID=1,等待WREADY=1) +2.写响应通道:等待BVALID=1,然后桥接模块设置PREADY=1,并传递BRESP(给PSLVERR,0表示OK,1表示错误)。 +注意:AXI4的写操作是先发送地址和数据,然后等待响应,而APB是先设置地址和数据,再使能传输。 + +特别地在这里对于AXI 64bit wdata中通过APB32bit总线配置写,寄存器地址位宽是64bit,连续相邻寄存器地址间隔是8; +![alt text](image-4.png) +在这里AXI地数据位宽是64bit,而APB的总线位宽是32bit,支持窄访问是32bit; +![alt text](企业微信截图_17531479011747.png) +假如说想配置写0x19f0的64bit; 我理解是: +APB(32位)发起两笔写transaction: +第一笔写低32位:paddr = 0x19f0; pwdata = 32'xx; ----> AXI: awaddr = 0x19f0; wdata = pwdata; wstrb = 8'h0F;wsize = 3'b010; +第二笔写高32位:paddr = 0x19f4; pwdata = 32'xxx; ----> AXI: awaddr = 0x19f4; wdata = pwdata ; wstrb = 8'hF0; wsize = 3'b010; + +### 4.1.2 读操作 +APB发起读:设置PADDR, PWRITE=0, PSEL=1,紧接着PENABLE=1。 +1.桥接模块将读地址发送到AXI4的读地址通道(ARVALID=1,等待ARREADY=1)。 +2.等待读数据通道返回(RVALID=1),然后读取数据,传递给PRDATA,并设置PREADY=1,同时传递RRESP(给PSLVERR)。 + +特别地在这里进行对于AXI 64bit中 rdata访问获取32bit; +![alt text](image-5.png) +假如说想配置读0x19f0的64bit; 我理解是: +APB(32位)发起两笔读transaction: +第一笔写低32位:paddr = 0x19f0; ; ----> AXI: awaddr = 0x19f0; prdata = (paddr[2]) ? rdata[64 -1:32] : [32 -1:0]; +第二笔写高32位:paddr = 0x19f4; ; ----> AXI: awaddr = 0x19f4;prdata = (paddr[2]) ? rdata[64 -1:32] : [32 -1:0] ; + +## 4.2 状态机设计 + +![alt text](image-6.png) \ No newline at end of file diff --git a/rtl/eth_mac/apb2axi_read.json b/rtl/eth_mac/apb2axi_read.json new file mode 100644 index 0000000..1230fce --- /dev/null +++ b/rtl/eth_mac/apb2axi_read.json @@ -0,0 +1,49 @@ +{ + "signal": [ + { "name": "clk", "wave": "P........", "period": 1 }, + { "name": "rst_n", "wave": "1........" }, + + + { "name": "PSEL", "wave": "0.1....0.", "node": ".." }, + { "name": "PENABLE", "wave": "0..1...0.", "node": "...a...b" }, + { "name": "PWRITE", "wave": "0.......", "data": ["", "Read"] }, + { "name": "PADDR", "wave": "x.3....x", "data": ["", "0x2000"] }, + { "name": "PRDATA", "wave": "x.....4x.", "data": ["", "", "0xCAFEBABE"] }, + { "name": "PREADY", "wave": "1..0..1x", "node": "...c..d" }, + { "name": "PSLVERR", "wave": "0......." }, + + {}, + { "name": "FSM", "wave": "=..=.=.=.", "data": ["IDLE","AR","R","IDLE"]}, + {}, + + { "name": "ARVALID", "wave": "0..1.0...", "node": "...g" }, + { "name": "ARID", "wave": "=........", "data": "0"}, + { "name": "arburst", "wave": "=........", "data": "2'b01"}, + { "name": "arsize", "wave": "=........", "data": "3'b010"}, + { "name": "ARADDR", "wave": "x..3.x...", "data": ["16'hxxxx", ] }, + { "name": "ARREADY", "wave": "0...10..", "node": "..." }, + {}, + + { "name": "RREADY", "wave": "1........", "node": "....." }, + { "name": "RVALID", "wave": "0.....10", "node": "......e" }, + { "name": "RDATA", "wave": "x.....4x.", "data": ["64'hxx",] }, + { "name": "RRESP", "wave": "x.....2x.", "data": ["OKAY", ] }, + + ], + + "edge": [ + "a<->b ACCESS ", + "c~>e ", + "e->d" + ], + + "head": { + "text": "APB3 到 AXI4 读操作转换时序", + "tick": 0 + }, + + "foot": { +// "text": "时序说明:1. APB SETUP阶段(1周期) → 2. APB ACCESS阶段(1周期) → 3. AXI地址通道 → 4. AXI数据通道", + "tick": 0 + } +} \ No newline at end of file diff --git a/rtl/eth_mac/apb2axi_write.json b/rtl/eth_mac/apb2axi_write.json new file mode 100644 index 0000000..83c88e2 --- /dev/null +++ b/rtl/eth_mac/apb2axi_write.json @@ -0,0 +1,59 @@ +{ + "signal": [ + { "name": "clk", "wave": "P............", "period": 1 }, + { "name": "rst_n", "wave": "01........" }, + + { "name": "PSEL", "wave": "0.1......0.", "node": "..b" }, + { "name": "PENABLE", "wave": "0..1.....0...", "node": "...c.....n" }, + { "name": "PWRITE", "wave": "0.1......x..", "data": ["", "Write"] }, + { "name": "PADDR", "wave": "x.3......x..", "data": ["", "0x1000"] }, + { "name": "PWDATA", "wave": "x.4......x..", "data": ["0xDEADBEEF", ""] }, + { "name": "PSLVERR", "wave": "0.........." }, + + { "name": "PREADY", "wave": "1..0....1..", "node": "...d....o" }, + {}, + + {"name": "FSM", "wave": "=..=.==..=.", "data": ["IDLE","AW_W","W","B","IDLE"]}, + {}, + + {"name": "AWVALID", "wave": "0..1.0..", "node": "..." }, + {"name": "AWBURST", "wave": "=.......", "data": ["2'b01"]}, + {"name": "AWLEN", "wave": "=.......", "data": ["0"]}, + {"name": "AWSIZE", "wave": "=.......", "data": ["3'b010"]}, + {"name": "AWADDR", "wave": "x..3.x..", "data": ["16'hxxxx" ] }, + {"name": "AWREADY", "wave": "0...1x..", "node": "...." }, + {}, + + {"name": "WVALID", "wave": "0..1..0.", "node": "......" }, + {"name": "wlast", "wave": "1......."}, + {"name": "WSTRB", "wave": "x..=..=.", "data": ["8'h0F/8'hF0" ] }, + {"name": "WDATA", "wave": "x..=..=.", "data": ["64'hxxxx"] }, + {"name": "WREADY", "wave": "0....1x.", "node": "....." }, + {}, + + { "name": "BREADY", "wave": "1.........", "node": "....." }, + { "name": "BVALID", "wave": "0.......10", "node": "........r" }, + { "name": "BID", "wave": "=.........", "data": ["0"]}, + { "name": "BRESP", "wave": "=.......2.", "data": ["OKAY", "OKAY"] } + ], + + "edge": [ + "a~b SETUP阶段开始", + "b~c SETUP", + "c<->n ACCESS", + "c~>o HOLD", + "o~>n " , + "d~>r ", + "r~>o " + ], + + "head": { + "text": "APB3 到 AXI4 写操作转换时序", + "tick": 0 + }, + + "foot": { +// "text": "时序说明:1. APB SETUP阶段(1周期) → 2. APB ACCESS阶段(1周期) → 3. AXI地址通道 → 4. AXI数据通道 → 5. AXI响应通道", + "tick": 0 + } +} \ No newline at end of file diff --git a/rtl/eth_mac/image-1.png b/rtl/eth_mac/image-1.png new file mode 100644 index 0000000..49840ed Binary files /dev/null and b/rtl/eth_mac/image-1.png differ diff --git a/rtl/eth_mac/image-2.png b/rtl/eth_mac/image-2.png new file mode 100644 index 0000000..3cf000b Binary files /dev/null and b/rtl/eth_mac/image-2.png differ diff --git a/rtl/eth_mac/image-3.png b/rtl/eth_mac/image-3.png new file mode 100644 index 0000000..9727ac8 Binary files /dev/null and b/rtl/eth_mac/image-3.png differ diff --git a/rtl/eth_mac/image-4.png b/rtl/eth_mac/image-4.png new file mode 100644 index 0000000..68e6a4c Binary files /dev/null and b/rtl/eth_mac/image-4.png differ diff --git a/rtl/eth_mac/image-5.png b/rtl/eth_mac/image-5.png new file mode 100644 index 0000000..2bd276f Binary files /dev/null and b/rtl/eth_mac/image-5.png differ diff --git a/rtl/eth_mac/image-6.png b/rtl/eth_mac/image-6.png new file mode 100644 index 0000000..276936d Binary files /dev/null and b/rtl/eth_mac/image-6.png differ diff --git a/rtl/eth_mac/image-7.png b/rtl/eth_mac/image-7.png new file mode 100644 index 0000000..c8b8222 Binary files /dev/null and b/rtl/eth_mac/image-7.png differ diff --git a/rtl/eth_mac/image-8.png b/rtl/eth_mac/image-8.png new file mode 100644 index 0000000..d564bdc Binary files /dev/null and b/rtl/eth_mac/image-8.png differ diff --git a/rtl/eth_mac/image-9.png b/rtl/eth_mac/image-9.png new file mode 100644 index 0000000..4af3d38 Binary files /dev/null and b/rtl/eth_mac/image-9.png differ diff --git a/rtl/eth_mac/image.png b/rtl/eth_mac/image.png new file mode 100644 index 0000000..057cd72 Binary files /dev/null and b/rtl/eth_mac/image.png differ diff --git a/rtl/eth_mac/企业微信截图_17531479011747.png b/rtl/eth_mac/企业微信截图_17531479011747.png new file mode 100644 index 0000000..c362203 Binary files /dev/null and b/rtl/eth_mac/企业微信截图_17531479011747.png differ