一、为什么“8 位地址”和“32 位地址”交替出现？
32 位地址总线：MIPS 地址总线为 32 位，可寻址 
2
32
=
4
GB
2 
32
 =4 GB 空间。

按字节编址：每个地址对应 1 字节（8 位），所以有“8 位视角”。

按字访问：MIPS 绝大多数指令按 32 位字访问，要求地址 4 字节对齐（低 2 位为 00）。

本质：编址粒度是字节（8 位），传输粒度是字（32 位），两者不矛盾。

二、存储器参数 Width / Depth
Width = 32 位：每个存储单元字长 32 位（4 字节）。

Depth = 64：共 64 个存储单元。

总容量 = 64 × 32 位 = 2048 位 = 256 字节。

按字节编址：地址范围 0 x 00 ~ 0 xFF（8 位地址）。

按字编址：字地址范围 0 x 00 ~ 0 x 3 F（6 位字地址）。

对话中多次出现“字地址最大为 60（0 x 3 C）”，可能原因是实验只开放前 61 个字，剩余 3 个字保留或未使用。

三、位序 MSB-LSB 与存储单元字长的混淆
位序 [7:0] 通常描述一个字节内部的位编号。

若存储单元是 32 位，整体位序应为 [31:0]，由 4 个字节拼接：

[31:24] Byte 3（MSB）

[23:16] Byte 2

[15:8] Byte 1

[7:0] Byte 0（LSB）

“7-0”不是指整个存储单元只有 8 位，而是字节内部的位序。

四、字地址与字节地址的映射
字地址 
𝑁
N 对应字节地址 
4
𝑁
∼
4
𝑁
+
3
4 N∼4 N+3。

例如：

字地址 0 → 字节地址 0 x 00~0 x 03

字地址 1 → 字节地址 0 x 04~0 x 07

字地址 60 → 字节地址 0 xF 0~0 xF 3

小端序下，低字节存放在低地址；大端序下，高字节存放在低地址。

五、Mem 模块分析
模块组成：

REGS：32 个 32 位寄存器，双端口读、单端口写。

ALU：支持与、或、异或、加法、减法、比较、移位等。

RAM_B：64×32 位单端口 RAM，按字访问，地址取 Mem_Addr[7:2]。

关键连接：

verilog
复制
下载
assign B = {{16{1'b0}} , offset};   // 零扩展（有问题，应为符号扩展）
assign Mem_Addr = ALU_F[7:0];      // 取低 8 位作为字节地址
RAM_B Data_RAM (
  .addra(Mem_Addr[7:2]),           // 字地址 = 字节地址右移 2 位
  .dina(R_data_B),
  .douta(M_R_Data)
);
潜在问题：

offset 零扩展：若 offset 为负数，应符号扩展。

寄存器 $0 未硬连线为 0：RISC-V 要求 x 0 恒为 0。

缺少地址对齐异常处理。

六、MIPS 指令语义
1. lw $3, 4($2)
地址 = $2 + 4

从该地址读 32 位字 → 存入 $3

2. sw $3, 24($0)
地址 = $0 + 24 = 24

将 $3 的值写入该地址

3. lw $4, 24($0)
地址 = $0 + 24 = 24

从该地址读 32 位字 → 存入 $4

七、RISC-V add 指令
格式：add rd, rs 1, rs 2

语义：REG[rd] ← REG[rs 1] + REG[rs 2]

不是 rs 1 + rs 2 → rd（寄存器编号相加）。

硬件只做二进制加法，不区分有符号/无符号；溢出需靠标志位或软件判断。

八、符号扩展 SE 32(imm 12)
符号扩展不是简单补 20 个 0。

规则：

若 imm 12[11] = 0，高 20 位补 0。

若 imm 12[11] = 1，高 20 位补 1。

公式： {{20{imm12[11]}} , imm 12}

九、补码统一有符号与无符号加减法
补码使加法器硬件无需区分符号。

示例：

0101 + 1101 = 10010，截断为 0010

无符号：5 + 13 = 18 mod 16 = 2

有符号：+5 + (-3) = +2

无符号溢出看进位 CF，有符号溢出看 OF。

十、存储字节 sb 与地址高低位
寄存器是 32 位，sb 只取低 8 位 Reg[rs 2][7:0]。

Mem 8[addr] 表示地址 addr 处的单个字节。

地址低 2 位决定字内字节位置（小端序）：

00 → Byte 0 [7:0]

01 → Byte 1 [15:8]

10 → Byte 2 [23:16]

11 → Byte 3 [31:24]

十一、访问尺寸 vs 寻址方式
访问尺寸：一次操作多少数据（字节/半字/字）。

寻址方式：如何计算地址（基址+偏移、PC 相对等）。

两者独立，可自由组合。

十二、Mem 16 存储位置
Mem 16[EA] 操作地址 EA 和 EA+1 两个字节。

具体高低字节顺序取决于字节序：

小端序：EA 存低字节，EA+1 存高字节。

大端序：EA 存高字节，EA+1 存低字节。

不会覆盖 EA-1。

十三、大端序判断示例
若内存 0 x 04~0 x 07 的值为 0 x 00632020，执行 lw $1, 4($0) 后 $1 = 0 x 00632020。

说明：

大端序：0 x 04=0 x 00, 0 x 05=0 x 63, 0 x 06=0 x 20, 0 x 07=0 x 20

小端序则 lw 结果会不同。

因此该系统采用大端序。


## 一、左下角表格是否“少了行”？

**问题**：表格只显示到字地址 63，共 16 行，是不是应该有 64 行到 255？

**结论**：

- 物理实现是 **64 × 32 位**，即 **64 个字**，字地址 6 位（0~63）。
    
- 逻辑视图是 **256 × 8 位**，即 **256 字节**，字节地址 8 位（0~255）。
    
- 表格只是**示意性列出部分行**（如 0、4、…、60），用 `...` 表示省略，**不是缺少行**。
    
- 字地址 0 对应字节 0~3，字地址 1 对应字节 4~7，……字地址 63 对应字节 252~255。
    

---

## 二、每一行对应 8 位还是 32 位？

- 表格中**每一行对应一个 32 位字（4 字节）**，不是 8 位。
    
- 看到“0 是 0-7”是因为：
    
    - 字地址 0：字节 0~3
        
    - 字地址 1：字节 4~7
        
    - 连续两行覆盖字节 0~7，但每行仍是 32 位字。
        
- 小端模式下，字内排列为：
    
    - 字节 0：LSB
        
    - 字节 1
        
    - 字节 2
        
    - 字节 3：MSB
        

---

## 三、读取顺序：一定从低地址到高地址吗？

- **按字读取**（如 `lw`）：硬件一次性读取整个 32 位字，自动按小端规则重组，软件看到的是完整逻辑值。
    
- **按字节读取**（如 `lb`）：需明确指定地址，读取顺序由程序控制，硬件不强制从低到高。
    
- 总线传输通常从低地址开始，但对软件透明。
    

---

## 四、字节序的关键纠正

**原错误说法**：

> 同样字节序 `12 34 56 78`，大端识别为 `0x12345678`，小端识别为 `0x78563412`。

**正确理解**：

- 字节序**只影响数据在内存中的物理排列顺序**，不改变逻辑值。
    
- 无论大端还是小端，`lw` 读出的结果始终是 `0x12345678`。
    
- 小端内存布局：
    
    - 地址 0 x 00：0 x 78
        
    - 0 x 01：0 x 56
        
    - 0 x 02：0 x 34
        
    - 0 x 03：0 x 12
        
- 硬件会自动重组，程序员看到的寄存器值仍是 `0x12345678`。
    

---

## 五、为什么是 64×32 位？

- **64 行**：字地址 0~63，共 64 个存储单元。
    
- **每行 32 位**：每个单元存一个 32 位字（4 字节）。
    
- **总容量**：64 × 32 位 = 2048 位 = **256 字节**。
    
- 逻辑上按字节编址，地址 0 x 00~0 xFF，正好覆盖 256 字节。
    
- 地址转换：
    
    - 字地址 = 字节地址 >> 2
        
    - 字内偏移 = 字节地址 & 0 x 03
        

---

## 六、字地址必须 4 字节对齐

- 合法字地址：字节地址低 2 位必须为 `00`，如 `0x00、0x04、0x08、…、0xFC`。
    
- 非法字地址：如 `0x01、0x02、0x03`，不能用于 `lw/sw`，否则触发**地址不对齐异常**。
    
- 字节访问（`lb/sb`）可任意地址；半字访问（`lh/sh`）需 2 字节对齐。
    

---

## 七、“字地址按 0,4,8…递增”是否矛盾？

**不矛盾，但表述有歧义**：

- **字地址本身**：是连续的 6 位整数，`0, 1, 2, …, 63`。
    
- **字地址对应的起始字节地址**：是 `4 × 字地址`，即 `0x00, 0x04, 0x08, …, 0xFC`。
    
- 所以：
    
    - 字地址是 `0,1,2,…,63`
        
    - 起始字节地址是 `0,4,8,…,252`
        
- 类比：
    
    - 楼层 = 字地址（1 楼、2 楼、…）
        
    - 每层起始房间号 = 字节地址（0、4、8、…）
        
    - 每层有 4 个房间（4 字节）
        

**关键公式**：

text

字地址 n = 字节地址 >> 2
字节地址 = 字地址 × 4 + 字内偏移