diff --git a/docs/L01 Intro.md b/docs/L01 Intro.md index 93741b1..f682fbd 100644 --- a/docs/L01 Intro.md +++ b/docs/L01 Intro.md @@ -17,11 +17,11 @@ Dan Garcia教授介绍了课程的主题——“计算机体系结构中的伟 Garcia教授还特别指出,这门课程不仅仅关注单个计算机的工作原理,而是要从更广阔的视角,探讨在云端和移动设备等多种环境中计算机如何运作。 -![image-20240429195107400](./assets/image-20240429195107400.png) +![image-20240429195107400]({{ site.baseurl }}/docs/assets/image-20240429195107400.png) --- -![image-20240429203333905](./assets/image-20240429203333905.png) +![image-20240429203333905]({{ site.baseurl }}/docs/assets/image-20240429203333905.png) ## 计算机体系结构中的 6 个伟大构想 @@ -29,19 +29,19 @@ Garcia教授还特别指出,这门课程不仅仅关注单个计算机的工 抽象化是计算机科学中一个核心概念,它允许我们在不考虑底层细节的情况下,处理复杂的问题和系统。在这门课程中,抽象化的讨论从Python编程语言的使用案例开始,强调了在编程中对函数、库、值等元素的命名和使用。这种抽象化的思维方式同样适用于硬件设计,例如,将所有信息编码为二进制数(0和1),这是数字逻辑和计算机硬件设计的基础。此外强调了从上至下连续抽象的重要性,即每一层的抽象都建立在下一层的抽象之上。 -![image-20240429204110137](./assets/image-20240429204110137.png) +![image-20240429204110137]({{ site.baseurl }}/docs/assets/image-20240429204110137.png) ### No.2 摩尔定律( Moore’s Law) 摩尔定律是由英特尔联合创始人戈登·摩尔在1965年提出的,预测了集成电路上可容纳的晶体管数量大约每两年翻一番。这个定律不仅预示了技术的进步速度,还影响了计算成本的下降和计算能力的提升,从而推动了计算机架构和技术创新的快速发展。在课程中,通过展示从1972年的Intel 8008芯片到后来的Pentium芯片晶体管数量的爆炸性增长,直观展示了摩尔定律的实际效果。同时,讨论了摩尔定律如何成为芯片制造商的一种自我实现的预言,即他们总是以这个定律为目标,不断推动技术的极限。 -![moores](./assets/moores.jpg) +![moores]({{ site.baseurl }}/docs/assets/moores.jpg) ### No.3 局部性原理(Principle of Locality/Memory Hierarchy) 局部性原理是计算机科学中的一个重要概念,它解释了为什么近距离存取数据比远距离存取数据要快得多。这一原理通过一个与人类大脑回忆过程相类比的例子来阐述:从大脑快速回忆近期信息,到较慢地回想起较远处或久远的信息,类似于从计算机的寄存器(最快)、缓存(较快)、主内存(较慢)、硬盘(最慢)中取数据的过程。这种类比帮助学生理解,在设计计算机系统时如何通过优化数据存取的“局部性”来提升系统性能。这种层次化的存储系统确保了高效访问频繁使用的数据,同时在成本和性能之间取得平衡。 -![image-20240429203909041](./assets/image-20240429203909041.png) +![image-20240429203909041]({{ site.baseurl }}/docs/assets/image-20240429203909041.png) ### No.4 并行性(Parallelism) @@ -55,7 +55,7 @@ Garcia教授还特别指出,这门课程不仅仅关注单个计算机的工 这些并行处理方式大幅度提高了处理效率,但也受到Amdahl定律的限制,该定律指出,一个程序的加速比最终受限于其必须顺序执行的部分。即使增加处理单元数量,总体性能提升也受到顺序执行代码部分的制约。 -![para3](./assets/para3.jpg) +![para3]({{ site.baseurl }}/docs/assets/para3.jpg) ### No.5 性能测量与提升(Performance Measurement and Improvement) diff --git a/docs/L02 Number Representation.md b/docs/L02 Number Representation.md index fd4e55a..d964cf1 100644 --- a/docs/L02 Number Representation.md +++ b/docs/L02 Number Representation.md @@ -18,7 +18,7 @@ nav_order: 2 进一步,教授解释了数字数据可以表示的各种内容,如字符、颜色和情绪等。强调了位(bit)的概念,即计算机中用于存储和处理信息的基本单位。每个位可以是0或1,通过组合位,可以表示更多的信息,例如5位可以有32种不同的设置,足以编码26个字母。 -![image-20240430143236301](./assets/image-20240430143236301.png) +![image-20240430143236301]({{ site.baseurl }}/docs/assets/image-20240430143236301.png) ### Bits can represent anything!! @@ -94,7 +94,7 @@ E. 无限个比特位 “哦,你一定是使用4进制。我使用10进制。” “不,我使用10进制。4进制是什么?” -![image-20240430141505448](./assets/image-20240430141505448.png) +![image-20240430141505448]({{ site.baseurl }}/docs/assets/image-20240430141505448.png) 这部分通过一幅幽默的漫画来解释数制的相对性。漫画中有两个角色,一个外星人和一个宇航员。外星人声称有10块石头,而宇航员误以为外星人是使用4进制,因为在10进制中10块石头就是10。这里的笑话在于,不同的数制中"10"代表的数量可能不同,但每个数制中的居民都认为他们使用的是“10进制”。 @@ -264,7 +264,7 @@ Literals (not supported by all compilers): - 通常不显示前导零 - 如果加法(或 -、*、/)的结果不能被这些最右边的硬件位表示,我们说**溢出**发生了 -![image-20240430134902023](./assets/image-20240430134902023.png) +![image-20240430134902023]({{ site.baseurl }}/docs/assets/image-20240430134902023.png) 在数字表示中,二进制位模式并不直接等同于它们所代表的数字,而是作为数字的抽象表达。在计算机科学中,数字是以二进制形式表达的,这称为数码。数码可以有无限长的位数,尽管我们通常只看到数值的有效位。当进行数值运算时,如果结果超出了硬件所能表示的位数范围,就会发生溢出。溢出是计算机科学中常见的问题,需要特别注意处理,以避免错误和不精确的计算结果。 @@ -348,7 +348,7 @@ Literals (not supported by all compilers): - = -8 + 5 - = -3_{10} -![image-20240430140716709](./assets/image-20240430140716709.png) +![image-20240430140716709]({{ site.baseurl }}/docs/assets/image-20240430140716709.png) 二的补码公式允许在有限的位数内准确地表示正数和负数。在这个例子中,我们看到了如何在4位二进制数(一个半字节)中表示十进制数-3。最高位的1表示负号,并且是2的3次方的负数。然后,每个后续位的值是2的相应次方乘以该位的值。最终结果显示了,尽管二进制表示似乎复杂,但通过这种方法可以精确地进行数值的算术计算。 @@ -361,7 +361,7 @@ Literals (not supported by all compilers): 二的补码数“线”是指以环形方式排列的二进制数,可以用于解释在有限的N位中能够表示的正数和负数的数量。当N=5时,我们可以表示2^{N-1}(或者16)个非负数和同样多的负数。在这个环中,有一个零,其余的位分别表示从-16(10000)到15(01111)的数。这种环形的表示法有助于理解二的补码如何能够在有限位数中循环表示数字,也展示了正数和负数之间的对称性。 -![image-20240430141035724](./assets/image-20240430141035724.png) +![image-20240430141035724]({{ site.baseurl }}/docs/assets/image-20240430141035724.png) ### 偏移编码:N = 5(偏移量 = -15) @@ -374,7 +374,7 @@ Literals (not supported by all compilers): 偏移编码是一种数字表示方法,它通过给无符号数加上一个偏差(或偏移量)来表示负数。在这种情况下,N位二进制数的偏差被设定为 -(2^{N-1}),例如,当N=5时,偏差为-15。这种方法类似于模拟信号处理中如何从一系列正数信号中产生负数,例如通过调整信号的中心点。在偏移编码中,只有一个零的表示,这样可以避免二进制表示法中的双零问题。 -![image-20240430141125200](./assets/image-20240430141125200.png) +![image-20240430141125200]({{ site.baseurl }}/docs/assets/image-20240430141125200.png) ### L02B 最佳表示-12.75的方式是什么?(解释移动二进制点) diff --git a/docs/L03 C Intro - Basics.md b/docs/L03 C Intro - Basics.md index 77f6541..f78df5d 100644 --- a/docs/L03 C Intro - Basics.md +++ b/docs/L03 C Intro - Basics.md @@ -69,7 +69,7 @@ C语言的一个核心特性是它允许程序员直接与硬件对话,并进 > - **汇编**:虽然在这张图中未详细说明,但在编译过程中,汇编是一个必要的步骤。源代码首先会被编译器转换为汇编代码,然后汇编器将汇编代码转换为机器码。 > - **链接器的作用**:链接器的作用是将多个目标文件(可能是程序的不同模块)以及必要的库文件组合在一起,生成最终的可执行文件。这一步骤是必要的,因为程序通常分为多个模块,编译生成多个目标文件后,需要通过链接器将它们结合起来,形成一个完整的可执行程序。 -![image-20240503212633211](./assets/image-20240503212633211.png) +![image-20240503212633211]({{ site.baseurl }}/docs/assets/image-20240503212633211.png) ## 文件协作与编译过程 @@ -120,7 +120,7 @@ C语言的一个核心特性是它允许程序员直接与硬件对话,并进 > > 这意味着,即使并行化的部分很大,如果串行部分的时间占比很小,整体加速效果仍然会受到限制。 -![image-20240503212704542](./assets/image-20240503212704542.png) +![image-20240503212704542]({{ site.baseurl }}/docs/assets/image-20240503212704542.png) @@ -156,11 +156,11 @@ C语言的一个核心特性是它允许程序员直接与硬件对话,并进 这部分内容对C语言和Java语言进行了比较。Java是一种面向对象的编程语言,强调封装和对象的管理,而C语言则是以函数为中心的,更注重具体函数的操作而不是对象。这两种语言在内存管理上有本质的差异:Java具有自动垃圾收集机制,可以自动管理内存,而C语言需要程序员显式地使用malloc和free等函数来管理内存。这种差异使得Java在编写代码时可能更为简便,但C语言在性能和底层操作上提供了更大的灵活性和控制力。 -![image-20240503212744860](./assets/image-20240503212744860.png) +![image-20240503212744860]({{ site.baseurl }}/docs/assets/image-20240503212744860.png) -![image-20240503212807408](./assets/image-20240503212807408.png) +![image-20240503212807408]({{ site.baseurl }}/docs/assets/image-20240503212807408.png) -![image-20240503212830130](./assets/image-20240503212830130.png) +![image-20240503212830130]({{ site.baseurl }}/docs/assets/image-20240503212830130.png) ### 1. 语言类型与编程单元 @@ -373,7 +373,7 @@ C语言虽然是一种较老的编程语言,但通过不断的更新和改进 | long | 较长的整数,至少32位 | 0, 78, -217, 301720971 | | long long | 更长的整数,至少64位 | 31705192721092512 | -![image-20240503213002534](./assets/image-20240503213002534.png) +![image-20240503213002534]({{ site.baseurl }}/docs/assets/image-20240503213002534.png) @@ -569,7 +569,7 @@ C语言提供了强大的语法和结构来支持高级编程需求,如数据 计算正弦函数值的表格,并输出角度和对应的正弦值。 -![image-20240503213414565](./assets/image-20240503213414565.png) +![image-20240503213414565]({{ site.baseurl }}/docs/assets/image-20240503213414565.png) 这段C程序的主要功能是计算并打印从0度到360度的正弦值(Sine values)。代码分析如下: diff --git a/docs/L04 C Intro - Pointers, Arrays, Strings.md b/docs/L04 C Intro - Pointers, Arrays, Strings.md index ed231ca..fa73fe8 100644 --- a/docs/L04 C Intro - Pointers, Arrays, Strings.md +++ b/docs/L04 C Intro - Pointers, Arrays, Strings.md @@ -562,7 +562,7 @@ int main() { - 假设 `ptr2` 指向一个已初始化的 `Coord` 结构体 `{3, 4}`,其地址为 `0x100`。 - 执行 `ptr1 = ptr2;` 后,`ptr1` 也指向地址 `0x100`,即与 `ptr2` 指向相同的结构体。 -![image-20240728220143258](./assets/image-20240728220143258.png) +![image-20240728220143258]({{ site.baseurl }}/docs/assets/image-20240728220143258.png) #### 选择题解释 @@ -1055,7 +1055,7 @@ printf("*a: %d, a: %x, &a: %x\n", *a, a, &a); - 2字节(16位)的数据类型(如 `short`)通常对齐到2字节边界。 - 1字节(8位)的数据类型(如 `char`)可以存储在任何地址上。 -![image-20240728220556327](./assets/image-20240728220556327.png) +![image-20240728220556327]({{ site.baseurl }}/docs/assets/image-20240728220556327.png) ### 示例图示 diff --git a/docs/L05 Memory (Mis)Management.md b/docs/L05 Memory (Mis)Management.md index 6e83f8f..b338e66 100644 --- a/docs/L05 Memory (Mis)Management.md +++ b/docs/L05 Memory (Mis)Management.md @@ -47,7 +47,7 @@ int main() { - **0x00000000** 部分是不可写/不可读的,因此在访问 `NULL` 指针时会崩溃。这种保护机制帮助捕捉对无效指针的访问。 -![image-20240730092540737](./assets/image-20240730092540737.png) +![image-20240730092540737]({{ site.baseurl }}/docs/assets/image-20240730092540737.png) ## Where are variables allocated? @@ -114,7 +114,7 @@ void d (int p) { 在这个例子中,当`main()`调用`a()`时,栈上会分配一个新的栈帧用于`a()`。然后`a()`调用`b()`,分配新的栈帧用于`b()`。依次类推,直到调用`d()`。在`d()`执行完后,`d()`的栈帧被移除,返回到`c()`,再依次回到`b()`、`a()`和`main()`,实现后进先出。 -![image-20240730094149780](./assets/image-20240730094149780.png) +![image-20240730094149780]({{ site.baseurl }}/docs/assets/image-20240730094149780.png) ## Passing Pointers into the Stack @@ -522,7 +522,7 @@ void free_mem_y() { ### 堆管理示例 -![image-20240730111140251](./assets/image-20240730111140251.png) +![image-20240730111140251]({{ site.baseurl }}/docs/assets/image-20240730111140251.png) 请求 R1,100 字节 -> 请求 R2,10 字节 -> 释放 R1 的内存 -> 请求 R3,50 字节 diff --git a/docs/L06 Floating Point.md b/docs/L06 Floating Point.md index 34e482b..8abaa69 100644 --- a/docs/L06 Floating Point.md +++ b/docs/L06 Floating Point.md @@ -57,7 +57,7 @@ nav_order: 6 - 计算方式:\\(1 \times 2^1 + 0 \times 2^0 + 1 \times 2^{-1} + 0 \times 2^{-2} + 1 \times 2^{-3} + 0 \times 2^{-4}\\) - 即:\\(2 + 0.5 + 0.125 = 2.625\\) -![image-20240730131919273](./assets/image-20240730131919273.png) +![image-20240730131919273]({{ site.baseurl }}/docs/assets/image-20240730131919273.png) **使用上述6位“固定二进制点”表示法的范围:** @@ -78,7 +78,7 @@ nav_order: 6 - 例如,计算 \\(1.1000 \times 0.0100\\) - 结果为:\\(0.1100\\) -![image-20240730131847561](./assets/image-20240730131847561.png) +![image-20240730131847561]({{ site.baseurl }}/docs/assets/image-20240730131847561.png) **需要记住二进制点的位置:** @@ -108,7 +108,7 @@ nav_order: 6 1. 存储这些“有效位”(significant bits)。 2. 记录最高有效位(MSB)左侧 2 位的二进制小数点(“指数字段”)。 -![image-20240730132906720](./assets/image-20240730132906720.png) +![image-20240730132906720]({{ site.baseurl }}/docs/assets/image-20240730132906720.png) **二进制点** 独立于有效位存储,因此可以表示非常大和非常小的数字。通过分离有效位和指数,我们可以动态调整二进制点的位置,从而扩展表示范围。 @@ -126,7 +126,7 @@ nav_order: 6 - 尾数(mantissa):1.640625 - 指数(exponent):-1 -![image-20240730133729508](./assets/image-20240730133729508.png) +![image-20240730133729508]({{ site.baseurl }}/docs/assets/image-20240730133729508.png) ## Enter Scientific Notation (in Binary) @@ -177,7 +177,7 @@ nav_order: 6 **浮点数表示形式:** - (-1)s × (1 + significand) × 2(exponent-127) -![image-20240730134907827](./assets/image-20240730134907827.png) +![image-20240730134907827]({{ site.baseurl }}/docs/assets/image-20240730134907827.png) ### 详细解释 @@ -366,7 +366,7 @@ nav_order: 6 -3.4×10^38 ---- -1.2×10^-38 ---- 0 ---- 1.2×10^-38 ---- 3.4×10^38 ``` -![image-20240730142300993](./assets/image-20240730142300993.png) +![image-20240730142300993]({{ site.baseurl }}/docs/assets/image-20240730142300993.png) **如果数字超出此范围会怎样?** @@ -450,7 +450,7 @@ s 1111 1111 xxx...xxxxx 由于使用了归一化形式和隐含的1,在零附近的表示间隔较大,导致数值精度不足。 -![image-20240730143147625](./assets/image-20240730143147625.png) +![image-20240730143147625]({{ site.baseurl }}/docs/assets/image-20240730143147625.png) ## Denorms: Gradual Underflow (2/2) @@ -484,7 +484,7 @@ s 0000 0000 xxx...xxxxx 非规范化数允许表示更接近零的数值,提供了更高的精度,避免了在接近零时出现的数值间隙。 -![image-20240730145436728](./assets/image-20240730145436728.png) +![image-20240730145436728]({{ site.baseurl }}/docs/assets/image-20240730145436728.png) > ## 规范化数与非规范化数的设计逻辑 > @@ -608,7 +608,7 @@ s 0000 0000 xxx...xxxxx - **指数(Exponent)**:11位 - **有效数字(Significand)**:52位 -![image-20240730151048083](./assets/image-20240730151048083.png) +![image-20240730151048083]({{ site.baseurl }}/docs/assets/image-20240730151048083.png) **双精度(vs. 单精度)** @@ -681,13 +681,13 @@ s 0000 0000 xxx...xxxxx - **BFLOAT16**(半精度浮点数的变种):用于深度学习,保留了FP32的指数范围,但减少了有效数字的位数,以更快地进行训练。 - **TF32**(张量浮点数):主要用于张量计算,结合了FP16和FP32的特点,提升了计算速度和效率。 -![image-20240730151304138](./assets/image-20240730151304138.png) +![image-20240730151304138]({{ site.baseurl }}/docs/assets/image-20240730151304138.png) ## Who Uses What in Domain Accelerators? ### 域加速器中谁使用什么? -![image-20240730151406513](./assets/image-20240730151406513.png) +![image-20240730151406513]({{ site.baseurl }}/docs/assets/image-20240730151406513.png) - 各种域加速器采用不同的浮点数表示形式以优化特定的计算任务。 - 例如,Google TPU v2和v3广泛使用int8和fp16用于机器学习加速。 diff --git a/docs/L07 Intro to Assembly Language, RISC-V.md b/docs/L07 Intro to Assembly Language, RISC-V.md index 9a5d60a..7994d97 100644 --- a/docs/L07 Intro to Assembly Language, RISC-V.md +++ b/docs/L07 Intro to Assembly Language, RISC-V.md @@ -247,13 +247,13 @@ sw x3, 4(x10) **硬件架构描述(例如,块图):** -![image-20240731104022846](./assets/image-20240731104022846.png) +![image-20240731104022846]({{ site.baseurl }}/docs/assets/image-20240731104022846.png) - 硬件架构描述包括CPU的设计和功能模块。块图显示了处理器的各个部分如何连接和交互。 **逻辑电路描述(电路原理图):** -![image-20240731104106063](./assets/image-20240731104106063.png) +![image-20240731104106063]({{ site.baseurl }}/docs/assets/image-20240731104106063.png) - 电路原理图描述了物理电路的布局和连接方式。这一步骤详细描述了实际硬件组件如何实现逻辑功能。 @@ -414,7 +414,7 @@ add x1, x2, x3 - **寄存器(Registers)**:用于存储数据和指令,直接内置于处理器中,非常快速。 - **算术逻辑单元(Arithmetic Logic Unit, ALU)**:执行算术和逻辑运算。 -![image-20240731105619891](./assets/image-20240731105619891.png) +![image-20240731105619891]({{ site.baseurl }}/docs/assets/image-20240731105619891.png) 寄存器直接在硬件中,因此速度非常快(比0.25纳秒更快)。 @@ -553,7 +553,7 @@ RISC-V: sub x4, x5, x6 # x4 = x5 - x6 C: d = e - f; ``` -![image-20240731112615998](./assets/image-20240731112615998.png) +![image-20240731112615998]({{ site.baseurl }}/docs/assets/image-20240731112615998.png) **重要提示:** diff --git a/docs/L08 RISC-V Data Transfer.md b/docs/L08 RISC-V Data Transfer.md index 82500d8..113fc6d 100644 --- a/docs/L08 RISC-V Data Transfer.md +++ b/docs/L08 RISC-V Data Transfer.md @@ -165,7 +165,7 @@ addi rd, rs1, imm - **Processor**(处理器)中的寄存器存储的数据非常快,但存储空间有限。 - **Memory**(内存)中存储的数据空间更大,但访问速度较慢。 -![image-20240731142456297](./assets/image-20240731142456297.png) +![image-20240731142456297]({{ site.baseurl }}/docs/assets/image-20240731142456297.png) 在RISC-V中,有多种指令用于加载和存储数据: @@ -192,7 +192,7 @@ sw x5, 4(x10) # 将寄存器 x5 中的数据存储到内存地址 x10 加 4 在一个字(32位)中,字节的地址如下所示: -![image-20240731142721682](./assets/image-20240731142721682.png) +![image-20240731142721682]({{ site.baseurl }}/docs/assets/image-20240731142721682.png) 最右边的字节0的地址是最小的。 @@ -210,7 +210,7 @@ sw x5, 4(x10) # 将寄存器 x5 中的数据存储到内存地址 x10 加 4 - **物理内存**(Physical Memory):快速、价格合理、中等容量。包括RAM,存取速度在几十纳秒到百纳秒之间。 - **存储层次结构**:从核心(Core)到寄存器(Registers)、物理内存(RAM),再到更大的存储(例如硬盘),存取速度逐渐变慢,但存储容量逐渐变大。硬盘和SSD的存取速度在毫秒到微秒级别。 -![image-20240731142921591](./assets/image-20240731142921591.png) +![image-20240731142921591]({{ site.baseurl }}/docs/assets/image-20240731142921591.png) **局部性原理** diff --git a/docs/L09 RISC-V Decision Making Logic Ops.md b/docs/L09 RISC-V Decision Making Logic Ops.md index 151f5f2..3de3b39 100644 --- a/docs/L09 RISC-V Decision Making Logic Ops.md +++ b/docs/L09 RISC-V Decision Making Logic Ops.md @@ -112,7 +112,7 @@ if (i == j) 有时可能需要对分支条件进行取反。此时,可以使用 `bne` 来处理原本使用 `beq` 的条件。 -![image-20240731155142682](./assets/image-20240731155142682.png) +![image-20240731155142682]({{ site.baseurl }}/docs/assets/image-20240731155142682.png) ## Example if-else Statement @@ -146,7 +146,7 @@ else 5. `Exit:` 标记结束,程序继续从这里执行。 -![image-20240731155211095](./assets/image-20240731155211095.png) +![image-20240731155211095]({{ site.baseurl }}/docs/assets/image-20240731155211095.png) @@ -244,7 +244,7 @@ Loop: Done: ``` -![image-20240731155720194](./assets/image-20240731155720194.png) +![image-20240731155720194]({{ site.baseurl }}/docs/assets/image-20240731155720194.png) - **初始化**: - `add x9, x8, x0`:将数组 `A` 的起始地址存储到寄存器 `x9`。 @@ -388,7 +388,7 @@ RISC-V 提供了算术右移指令,用于将寄存器中的值向右移动, - 汇编器将其转换为机器代码目标文件(.o 文件) - 链接器将多个目标文件和预构建的目标文件库(lib.o)链接成一个可执行的机器代码文件(a.out) -![image-20240731160506346](./assets/image-20240731160506346.png) +![image-20240731160506346]({{ site.baseurl }}/docs/assets/image-20240731160506346.png) ## How Program is Stored @@ -401,7 +401,7 @@ RISC-V 提供了算术右移指令,用于将寄存器中的值向右移动, 一个 RISC-V 指令占用 32 位(4 字节)。 -![image-20240731160556472](./assets/image-20240731160556472.png) +![image-20240731160556472]({{ site.baseurl }}/docs/assets/image-20240731160556472.png) ## Program Execution @@ -413,7 +413,7 @@ RISC-V 提供了算术右移指令,用于将寄存器中的值向右移动, 2. 控制单元使用数据路径和内存系统执行指令,并更新程序计数器。 3. 默认情况下,PC 加 4 字节以移动到下一个顺序指令;分支和跳转指令会改变这个默认行为。 -![image-20240731160629405](./assets/image-20240731160629405.png) +![image-20240731160629405]({{ site.baseurl }}/docs/assets/image-20240731160629405.png) ## Helpful RISC-V Assembler Features diff --git a/docs/L10 RISC-V Procedures.md b/docs/L10 RISC-V Procedures.md index 1b3cd4b..742d4b4 100644 --- a/docs/L10 RISC-V Procedures.md +++ b/docs/L10 RISC-V Procedures.md @@ -483,7 +483,7 @@ Leaf: - 需要保存 `s0` 和 `s1` 的旧值。 -![image-20240801104036868](./assets/image-20240801104036868.png) +![image-20240801104036868]({{ site.baseurl }}/docs/assets/image-20240801104036868.png) diff --git a/docs/L11 RISC-V Instruction Formats I.md b/docs/L11 RISC-V Instruction Formats I.md index badd3ad..629f280 100644 --- a/docs/L11 RISC-V Instruction Formats I.md +++ b/docs/L11 RISC-V Instruction Formats I.md @@ -25,7 +25,7 @@ nav_order: 11 每一层都为下一层提供了更高层次的抽象,简化了设计和编程的复杂度。 -![image-20240801114118927](./assets/image-20240801114118927.png) +![image-20240801114118927]({{ site.baseurl }}/docs/assets/image-20240801114118927.png) ### 快速计算机科学历史:ENIAC(宾夕法尼亚大学,1946年) @@ -100,7 +100,7 @@ opname rd, rs1, rs2 指令被分为多个字段,每个字段在指令字中的位置和大小如下图所示: -![image-20240801115609252](./assets/image-20240801115609252.png) +![image-20240801115609252]({{ site.baseurl }}/docs/assets/image-20240801115609252.png) **字段的作用** @@ -111,7 +111,7 @@ opname rd, rs1, rs2 - **rs2**:源寄存器2字段,包含第二个操作数(5位无符号整数)。 - **funct7**:与funct3和opcode组合描述要执行的操作。 -![image-20240801115729275](./assets/image-20240801115729275.png) +![image-20240801115729275]({{ site.baseurl }}/docs/assets/image-20240801115729275.png) ### 为什么不直接使用一个17位字段来表示操作? @@ -148,13 +148,13 @@ add x18, x19, x10 每个字段在指令字中的位置和大小如下图所示: -![image-20240801115805097](./assets/image-20240801115805097.png) +![image-20240801115805097]({{ site.baseurl }}/docs/assets/image-20240801115805097.png) ### RV32 R格式指令 以下是RV32 R格式指令的 `funct7` 和 `funct3` 字段编码: -![image-20240801115830297](./assets/image-20240801115830297.png) +![image-20240801115830297]({{ site.baseurl }}/docs/assets/image-20240801115830297.png) ### 如何编码 @@ -179,7 +179,7 @@ add x4, x3, x2 0000000 00010 00011 000 00100 0110011 ``` -![image-20240801120213407](./assets/image-20240801120213407.png) +![image-20240801120213407]({{ site.baseurl }}/docs/assets/image-20240801120213407.png) 转换为十六进制编码为: @@ -212,7 +212,7 @@ funct7 rs2 rs1 funct3 rd opcode 为了处理立即数,RISC-V引入了I格式。I格式保留了与R格式的大部分一致性,简化了CPU处理指令的方式。I格式指令布局如下: -![image-20240801120419736](./assets/image-20240801120419736.png) +![image-20240801120419736]({{ site.baseurl }}/docs/assets/image-20240801120419736.png) `imm[11:0]` 是12位宽的立即数,可以表示从 -2048 到 2047 的数值。CPU在使用前会将其符号扩展到32位。 @@ -238,11 +238,11 @@ addi x15, x1, -50 - **rd**:01111 (x15) - **opcode**:0010011 -![image-20240801120450473](./assets/image-20240801120450473.png) +![image-20240801120450473]({{ site.baseurl }}/docs/assets/image-20240801120450473.png) ### RV32 I格式算术指令 -![image-20240801120525644](./assets/image-20240801120525644.png) +![image-20240801120525644]({{ site.baseurl }}/docs/assets/image-20240801120525644.png) **总结** @@ -281,9 +281,9 @@ imm[11:0] rs1 funct3 rd opcode - **rd**:01110(x14) - **opcode**:0000011 -![image-20240801120645446](./assets/image-20240801120645446.png) +![image-20240801120645446]({{ site.baseurl }}/docs/assets/image-20240801120645446.png) -![image-20240801120702311](./assets/image-20240801120702311.png) +![image-20240801120702311]({{ site.baseurl }}/docs/assets/image-20240801120702311.png) ### 所有五种RV32加载指令 @@ -295,7 +295,7 @@ RISC-V定义了五种加载指令,每种指令的功能和编码如下: - **lbu**(加载无符号字节):funct3=100,opcode=0000011 - **lhu**(加载无符号半字):funct3=101,opcode=0000011 -![image-20240801120733288](./assets/image-20240801120733288.png) +![image-20240801120733288]({{ site.baseurl }}/docs/assets/image-20240801120733288.png) ### 加载操作的符号扩展和零扩展 @@ -360,7 +360,7 @@ Store address = (Base Register) + (Immediate Offset) 这条指令表示将寄存器x5中的数据存储到计算出的内存地址中。 -![image-20240801120952302](./assets/image-20240801120952302.png) +![image-20240801120952302]({{ site.baseurl }}/docs/assets/image-20240801120952302.png) ### S格式简化硬件设计 @@ -390,7 +390,7 @@ imm[11:5] rs2 rs1 funct3 imm[4:0] opcode - **imm[4:0]**:00100(低5位) - **opcode**:0100011(表示存储指令) -![image-20240801121147494](./assets/image-20240801121147494.png) +![image-20240801121147494]({{ site.baseurl }}/docs/assets/image-20240801121147494.png) ### 所有三种RV32存储指令 @@ -402,7 +402,7 @@ RISC-V定义了三种存储指令,分别用于不同的数据宽度: 这些指令通过立即数和两个寄存器操作数来指定存储操作的位置和数据内容。 -![image-20240801121821873](./assets/image-20240801121821873.png) +![image-20240801121821873]({{ site.baseurl }}/docs/assets/image-20240801121821873.png) ## 结论 @@ -414,6 +414,6 @@ RISC-V简化了指令格式,使所有指令的大小与数据字相同(32位 - **R格式**:用于寄存器到寄存器的算术操作 - **S格式**:用于存储指令 -![image-20240801121852778](./assets/image-20240801121852778.png) +![image-20240801121852778]({{ site.baseurl }}/docs/assets/image-20240801121852778.png) 未来还将介绍B格式、U格式和J格式指令格式,这些格式进一步扩展了RISC-V指令集的功能和应用场景。 diff --git a/docs/L12 RISC-V Instruction Formats II.md b/docs/L12 RISC-V Instruction Formats II.md index 8dffb23..4d8f0a6 100644 --- a/docs/L12 RISC-V Instruction Formats II.md +++ b/docs/L12 RISC-V Instruction Formats II.md @@ -17,7 +17,7 @@ nav_order: 12 程序计数器(PC)是处理器内部的一个特殊寄存器,用于保存当前执行指令的字节地址。它与32个通用寄存器文件分开,专门用于控制程序的执行流。 -![image-20240801145611459](./assets/image-20240801145611459.png) +![image-20240801145611459]({{ site.baseurl }}/docs/assets/image-20240801145611459.png) ## PC = PC + 4用于大多数指令 @@ -47,7 +47,7 @@ PC: 0x00000014 这个机制确保了程序的顺序执行,即逐条指令按顺序被处理。 -![image-20240801145800527](./assets/image-20240801145800527.png) +![image-20240801145800527]({{ site.baseurl }}/docs/assets/image-20240801145800527.png) ## 分支更新PC以进行“跳转” @@ -67,7 +67,7 @@ PC: 0x00000014 PC: 0x0000000c ``` -![image-20240801150017324](./assets/image-20240801150017324.png) +![image-20240801150017324]({{ site.baseurl }}/docs/assets/image-20240801150017324.png) ### 条件分支 @@ -105,7 +105,7 @@ PC = PC + byte_offset 如果 `beq` 分支不成立,PC 更新为 `PC + 4`,即 `0x10`。 -![image-20240801150140932](./assets/image-20240801150140932.png) +![image-20240801150140932]({{ site.baseurl }}/docs/assets/image-20240801150140932.png) ### 与绝对寻址对比 @@ -220,7 +220,7 @@ B-格式(课本称为SB-类型)接近于S-格式: - `imm[4:1|11]`(5位) - `opcode`(7位) -![image-20240801152031346](./assets/image-20240801152031346.png) +![image-20240801152031346]({{ site.baseurl }}/docs/assets/image-20240801152031346.png) ## B格式示例 @@ -245,7 +245,7 @@ beq x1, x2, Label 然后构建分支偏移量并编码立即数。 -![image-20240801152112523](./assets/image-20240801152112523.png) +![image-20240801152112523]({{ site.baseurl }}/docs/assets/image-20240801152112523.png) ### 示例2 @@ -260,7 +260,7 @@ beq x1, x2, Label 通过这些步骤,我们可以构建和理解B格式指令的编码和使用方式。 -![image-20240801152157535](./assets/image-20240801152157535.png) +![image-20240801152157535]({{ site.baseurl }}/docs/assets/image-20240801152157535.png) ## 为什么要打乱立即数位?硬件设计! @@ -277,7 +277,7 @@ beq x1, x2, Label 在所有格式中,位31总是符号位(最高位用于在立即数中符号扩展)。B型格式具有13位立即数编码,因为在imm位0处有隐含的零。这种设计降低了硬件成本,使得立即数处理更加高效。 -![image-20240801152318282](./assets/image-20240801152318282.png) +![image-20240801152318282]({{ site.baseurl }}/docs/assets/image-20240801152318282.png) ### 所有六个RV32 B格式指令 @@ -292,7 +292,7 @@ B格式指令用于条件分支,指令包括: 每个指令对应不同的funct3编码。 -![image-20240801152335579](./assets/image-20240801152335579.png) +![image-20240801152335579]({{ site.baseurl }}/docs/assets/image-20240801152335579.png) ## 进一步的条件分支 @@ -349,7 +349,7 @@ j Label J格式(或UJ类型)专用于 `jal` 指令。其布局如下: -![image-20240801152750600](./assets/image-20240801152750600.png) +![image-20240801152750600]({{ site.baseurl }}/docs/assets/image-20240801152750600.png) - **opcode**:1101111 - **rd**:目标寄存器,用于存储返回地址 @@ -372,7 +372,7 @@ U格式(Upper Immediate)指令: 立即数表示32位立即数操作数的高20位,实际值为`immed << 12`。 -![image-20240801152853601](./assets/image-20240801152853601.png) +![image-20240801152853601]({{ site.baseurl }}/docs/assets/image-20240801152853601.png) ## `lui`和`addi`创建长立即数 @@ -536,9 +536,9 @@ li x10, 0xBOBACAFE # 自动处理高位加1的问题 - 覆盖了几乎整个 RV32 ISA! - 练习汇编和反汇编! -![image-20240801140005974](./assets/image-20240801140005974.png) +![image-20240801140005974]({{ site.baseurl }}/docs/assets/image-20240801140005974.png) -![image-20240801140027147](./assets/image-20240801140027147.png) +![image-20240801140027147]({{ site.baseurl }}/docs/assets/image-20240801140027147.png) ### RISC-V 指令表中文解释 diff --git a/docs/L13 Compiler, Assembler, Linker, Loader.md b/docs/L13 Compiler, Assembler, Linker, Loader.md index 7ea6265..db26858 100644 --- a/docs/L13 Compiler, Assembler, Linker, Loader.md +++ b/docs/L13 Compiler, Assembler, Linker, Loader.md @@ -74,7 +74,7 @@ nav_order: 13 伪指令为汇编语言程序员提供了简洁方便的表达方式,而汇编器会将这些伪指令转换为等效的机器指令。 -![image-20240802093108364](./assets/image-20240802093108364.png) +![image-20240802093108364]({{ site.baseurl }}/docs/assets/image-20240802093108364.png) **CALL (Compiling, Assembling, Linking, and Loading)** 涉及程序从高级语言到机器语言的转换过程,以及进一步的硬件实现部分: @@ -129,7 +129,7 @@ nav_order: 13 总结:将C代码编译为二进制通常指的是步骤1-3,即将C程序转换为可执行文件。 -![image-20240802101722589](./assets/image-20240802101722589.png) +![image-20240802101722589]({{ site.baseurl }}/docs/assets/image-20240802101722589.png) # Compiler @@ -141,7 +141,7 @@ nav_order: 13 - **输出**:汇编语言代码(例如,`foo.s`,适用于RISC-V)。 - 注意:输出中**可能**包含伪指令(pseudoinstructions),例如,`mv`, `li`, `call`, `j`等。 -![image-20240802101821667](./assets/image-20240802101821667.png) +![image-20240802101821667]({{ site.baseurl }}/docs/assets/image-20240802101821667.png) # Assembler @@ -156,7 +156,7 @@ nav_order: 13 汇编器读取和使用指令(directives),并用真实的汇编代码替换伪指令,然后生成机器语言代码。 -![image-20240802101924226](./assets/image-20240802101924226.png) +![image-20240802101924226]({{ site.baseurl }}/docs/assets/image-20240802101924226.png) ## Directives @@ -371,7 +371,7 @@ Exit: ... - 包含文本段和数据段,以及每个文件的信息表。 - **输出**:可执行机器代码(例如,适用于RISC-V的a.out) -![image-20240802102952406](./assets/image-20240802102952406.png) +![image-20240802102952406]({{ site.baseurl }}/docs/assets/image-20240802102952406.png) ### 链接器的作用 @@ -387,7 +387,7 @@ Exit: ... - 遍历重定位表并处理每个条目,填写所有绝对地址。 -image-20240802103147530 +image-20240802103147530 ## 哪些地址需要重定位? @@ -506,7 +506,7 @@ Exit: ... - **输入**:可执行代码(例如,RISC-V的a.out) - **输出**:程序运行 -![image-20240802103807435](./assets/image-20240802103807435.png) +![image-20240802103807435]({{ site.baseurl }}/docs/assets/image-20240802103807435.png) ## 加载器的工作原理 @@ -566,7 +566,7 @@ int main() { 编译器将C代码转换为汇编代码。以下是生成的汇编代码示例: -![image-20240802104059647](./assets/image-20240802104059647.png) +![image-20240802104059647]({{ site.baseurl }}/docs/assets/image-20240802104059647.png) - `.text`:代码段 - `.align 2`:将代码对齐到2^2字节边界。 @@ -595,7 +595,7 @@ int main() { 汇编器将汇编代码转换为目标文件。以下是一些关键步骤: -![image-20240802104148761](./assets/image-20240802104148761.png) +![image-20240802104148761]({{ site.baseurl }}/docs/assets/image-20240802104148761.png) - **Text segment**:文本段 - 汇编器输出显示了每条指令的机器码。例如: @@ -677,7 +677,7 @@ a0500513 addi a0, a0, -1520 ### 语言执行连续性 -![image-20240802104738912](./assets/image-20240802104738912.png) +![image-20240802104738912]({{ site.baseurl }}/docs/assets/image-20240802104738912.png) 解释器是一种直接执行其他程序的程序。 diff --git a/docs/L14 Intro to Synchronous Digital Systems.md b/docs/L14 Intro to Synchronous Digital Systems.md index 8441096..8b23eeb 100644 --- a/docs/L14 Intro to Synchronous Digital Systems.md +++ b/docs/L14 Intro to Synchronous Digital Systems.md @@ -31,7 +31,7 @@ nav_order: 14 在计算机系统中,软件和硬件是相辅相成的。软件包括应用程序、操作系统、编译器和汇编器等,它们运行在硬件之上。硬件则由处理器、内存、输入/输出系统、数据路径和控制、数字设计、电路设计、晶体管和制造工艺等组成。CS61C课程涵盖了这些内容,特别是指令集架构(ISA),这是硬件和软件之间的重要接口。 -![image-20240429195107400](./assets/image-20240429195107400.png) +![image-20240429195107400]({{ site.baseurl }}/docs/assets/image-20240429195107400.png) ## New-School Machine Structures @@ -55,7 +55,7 @@ nav_order: 14 - **并行数据**:例如在向量处理器中,同时处理多个数据。 - **硬件并行**:所有逻辑门在同一时间并行工作,提高了硬件的整体性能。 -![image-20240802111951377](./assets/image-20240802111951377.png) +![image-20240802111951377]({{ site.baseurl }}/docs/assets/image-20240802111951377.png) ## Hardware Descriptions @@ -87,7 +87,7 @@ nav_order: 14 - **硬件架构描述(例如:块图)**:展示了系统的总体结构和各部分的功能。 - **逻辑电路描述(电路原理图)**:详细描述了逻辑门和其他硬件组件如何连接和协同工作。 -![image-20240802124821397](./assets/image-20240802124821397.png) +![image-20240802124821397]({{ site.baseurl }}/docs/assets/image-20240802124821397.png) 硬件架构设计的过程从总体结构开始,逐步细化到具体的电路实现。块图通常用于概述系统的各个模块及其相互连接,而电路原理图则展示了每个模块内部的详细设计。 @@ -145,7 +145,7 @@ nav_order: 14 这种简单的电路设计是数字电路的基础,通过控制电流的通断来实现基本的逻辑运算。通过这种基本的开关操作,可以构建更复杂的逻辑电路。 -![image-20240802125021572](./assets/image-20240802125021572.png) +![image-20240802125021572]({{ site.baseurl }}/docs/assets/image-20240802125021572.png) ### 组合开关以实现更复杂的逻辑功能(布尔函数) @@ -156,7 +156,7 @@ nav_order: 14 这些基本的布尔逻辑运算是所有数字电路的基础,通过这些基本运算,可以构建复杂的数字系统。组合逻辑设计包括各种基本门电路的组合和优化,旨在实现更高效的电路功能。 -![image-20240802125056709](./assets/image-20240802125056709.png) +![image-20240802125056709]({{ site.baseurl }}/docs/assets/image-20240802125056709.png) ## Historical Note @@ -211,7 +211,7 @@ MOS晶体管的工作原理是基于电压控制的开关,n型和p型晶体管 ***n型晶体管在栅极电压高时导通,而p型晶体管在栅极电压低时导通*。** -![image-20240802132000735](./assets/image-20240802132000735.png) +![image-20240802132000735]({{ site.baseurl }}/docs/assets/image-20240802132000735.png) 记忆提示 @@ -240,7 +240,7 @@ MOS网络通过组合n型和p型晶体管实现复杂的逻辑功能。图中展 这个电路的工作原理是通过控制输入电压x来决定输出电压y的状态,利用n型和p型晶体管的开关特性实现逻辑反转。总结来说,这个电路实现了一个简单的反相器(NOT门),输入信号x的电压高低状态与输出信号y的电压状态相反。 -![image-20240802132111622](./assets/image-20240802132111622.png) +![image-20240802132111622]({{ site.baseurl }}/docs/assets/image-20240802132111622.png) ## Transistor Circuit Representation vs. Block Diagram @@ -261,7 +261,7 @@ MOS网络通过组合n型和p型晶体管实现复杂的逻辑功能。图中展 这些基本逻辑门是构建复杂数字系统的基础,通过它们可以实现各种数字电路和逻辑运算。 -![image-20240802134908539](./assets/image-20240802134908539.png) +![image-20240802134908539]({{ site.baseurl }}/docs/assets/image-20240802134908539.png) @@ -279,7 +279,7 @@ MOS网络通过组合n型和p型晶体管实现复杂的逻辑功能。图中展 在数字系统中,时钟信号是所有操作的核心协调者。时钟信号是一个重复的方波,具有高电平(通常为3伏特)和低电平(通常为0伏特)。时钟周期(T)定义了高电平和低电平的持续时间,并且频率(freq)是时钟周期的倒数。时钟信号的作用是同步所有的操作,使系统的每个部分在同一时间点进行工作,从而确保数据的一致性和正确性。 -![image-20240802135055786](./assets/image-20240802135055786.png) +![image-20240802135055786]({{ site.baseurl }}/docs/assets/image-20240802135055786.png) ### 信号 @@ -298,7 +298,7 @@ MOS网络通过组合n型和p型晶体管实现复杂的逻辑功能。图中展 在下图中,展示了一个加法器电路中信号传输的情况,黄色箭头指示了噪声和延迟的存在。理解和处理这些因素对于设计可靠的数字系统至关重要。 -![image-20240802135326789](./assets/image-20240802135326789.png) +![image-20240802135326789]({{ site.baseurl }}/docs/assets/image-20240802135326789.png) 为了应对噪声和延迟,设计师需要采用各种技术,如屏蔽、滤波和信号调理,以确保信号的完整性和系统的可靠性。 @@ -313,7 +313,7 @@ MOS网络通过组合n型和p型晶体管实现复杂的逻辑功能。图中展 这种分组方式有助于分析信号在不同时间点的状态变化,并理解它们之间的逻辑关系。 -![image-20240802135353143](./assets/image-20240802135353143.png) +![image-20240802135353143]({{ site.baseurl }}/docs/assets/image-20240802135353143.png) 信号分组不仅在分析和调试过程中有用,还在设计复杂电路时帮助设计师更好地管理和组织信号。 @@ -327,7 +327,7 @@ MOS网络通过组合n型和p型晶体管实现复杂的逻辑功能。图中展 电路延迟的管理是设计高性能数字系统的关键。工程师们通过优化导线长度、减少逻辑门数量和使用更快的材料来减少延迟,从而提高系统的整体速度和效率。 -![image-20240802140145252](./assets/image-20240802140145252.png) +![image-20240802140145252]({{ site.baseurl }}/docs/assets/image-20240802140145252.png) > **导线表示法**: 在数字设计中,为了简化表示,我们使用斜线来表示多位导线。例如,一个标有“4”的导线表示两位导线。尽管图中只画了一根线,但实际上它表示的是4根导线。 @@ -378,7 +378,7 @@ MOS网络通过组合n型和p型晶体管实现复杂的逻辑功能。图中展 这些寄存器在数字系统中起到关键作用,它们用来存储指令、数据和状态信息。寄存器不仅用于简单的数据存储,还用于实现复杂的时序逻辑,如状态机和计数器。 -![image-20240802140721958](./assets/image-20240802140721958.png) +![image-20240802140721958]({{ site.baseurl }}/docs/assets/image-20240802140721958.png) ## And in Conclusion... diff --git a/docs/L15 Combinational Logic.md b/docs/L15 Combinational Logic.md index 652ce02..f873405 100644 --- a/docs/L15 Combinational Logic.md +++ b/docs/L15 Combinational Logic.md @@ -129,7 +129,7 @@ AND 门是一个基本的逻辑门,其输出只有在所有输入均为高电 - 符号: -image-20240802145851813 +image-20240802145851813 - 真值表: @@ -146,7 +146,7 @@ OR 门是一个基本的逻辑门,其输出在至少一个输入为高电平 - 符号: -image-20240802145919692 +image-20240802145919692 - 真值表: @@ -163,7 +163,7 @@ NOT 门是一个基本的逻辑门,其输出是输入的反相。输入为高 - 符号: -image-20240802145935341 +image-20240802145935341 - 真值表: @@ -180,7 +180,7 @@ XOR 门是一个逻辑门,其输出在两个输入不同(即一个为高电 - 符号: -image-20240802150346285 +image-20240802150346285 - 真值表: @@ -197,7 +197,7 @@ NAND 门是一个逻辑门,其输出是 AND 门输出的反相。只有在所 - 符号: -image-20240802150404489 +image-20240802150404489 - 真值表: @@ -214,7 +214,7 @@ NOR 门是一个逻辑门,其输出是 OR 门输出的反相。只有在所有 - 符号: -image-20240802150420172 +image-20240802150420172 - 真值表: @@ -259,7 +259,7 @@ NOR 门是一个逻辑门,其输出是 OR 门输出的反相。只有在所有 下图展示了三输入多数电路的真值表及其对应的逻辑电路。 -![image-20240802151202359](./assets/image-20240802151202359.png) +![image-20240802151202359]({{ site.baseurl }}/docs/assets/image-20240802151202359.png) ## Truth Table -> Gates (e.g., FSM circuit) @@ -270,7 +270,7 @@ NOR 门是一个逻辑门,其输出是 OR 门输出的反相。只有在所有 下图展示了一个简单的FSM电路的真值表及其对应的逻辑电路: -![image-20240802151339786](./assets/image-20240802151339786.png) +![image-20240802151339786]({{ site.baseurl }}/docs/assets/image-20240802151339786.png) 这里,PS表示当前状态,NS表示下一个状态,Input表示输入信号,Output表示输出信号。逻辑电路可以用与门和或门实现。 @@ -297,7 +297,7 @@ NOR 门是一个逻辑门,其输出是 OR 门输出的反相。只有在所有 这个表达式表示当三个输入中有两个或两个以上为真(1)时,输出为真(1)。 -![image-20240802151658698](./assets/image-20240802151658698.png) +![image-20240802151658698]({{ site.baseurl }}/docs/assets/image-20240802151658698.png) ## Boolean Algebra (e.g., for FSM) @@ -343,7 +343,7 @@ NOR 门是一个逻辑门,其输出是 OR 门输出的反相。只有在所有 简化后的表达式为: \\[ y = a + c \\] -![image-20240802151912234](./assets/image-20240802151912234.png) +![image-20240802151912234]({{ site.baseurl }}/docs/assets/image-20240802151912234.png) 原始电路通过化简可以变为更简单的电路,只需要一个或门即可实现上述功能。 @@ -423,7 +423,7 @@ NOR 门是一个逻辑门,其输出是 OR 门输出的反相。只有在所有 在图中,我们看到一个示例,该示例展示了如何将一个布尔表达式转换为SOP形式。这个例子的真值表如下: -![image-20240802152835541](./assets/image-20240802152835541.png) +![image-20240802152835541]({{ site.baseurl }}/docs/assets/image-20240802152835541.png) 我们可以看到,对于输出 y 为 1 的每一行,我们可以写出相应的最小项(minterm)。这些最小项可以用与 (AND) 操作组合起来,然后用或 (OR) 操作相连: @@ -458,7 +458,7 @@ NOR 门是一个逻辑门,其输出是 OR 门输出的反相。只有在所有 电路图如下: -![image-20240802153752111](./assets/image-20240802153752111.png) +![image-20240802153752111]({{ site.baseurl }}/docs/assets/image-20240802153752111.png) 1. **计算 \\(\overline{a} \cdot \overline{b}\\)**: - 使用两个 NOT 门将 \\(a\\) 和 \\(b\\) 分别反相。