Gokong Space | 行空空间 - 笔记
type: channel
link: https://gokong.space/tag/%E7%AC%94%E8%AE%B0/
items: 23级计院操作系统期末试题
items: 『操作系统』期末复习
items: Good First Issue 指南
items: Verilog 学习笔记（14）：More Circuits
items: Verilog 学习笔记（13）：Shift Registers
items: Verilog 学习笔记（12）：Counters
items: Verilog 学习笔记（11）：Latches and Flip-Flops
items: Verilog 学习笔记（9）：Arithmetic Circuits
items: Verilog 学习笔记（8）：Multiplexers
items: Verilog 学习笔记（7）：Basic Gates

23级计院操作系统期末试题
type: item
date: 2026-06-24T23:43:00+08:00
description: 23级计院操作系统期末试题 A 卷解析与答案本文根据 23级计院操作系统期末.pdf 整理。试卷结构比较典型：选择题覆盖概念辨析，后面大题集中考进程互斥同步、处理机调度、银行家算法、虚拟页式存储、磁盘调度和 PV 操作。一、单项选择答案汇总：题号答案简要解析1B现代操作系统最基本的两个特征是并发和共享。2C实时系统强调在被控对象规定的时间内响应并处理事件。3D启动设备、设置中断屏蔽、设置时钟通常是特权指令；读时钟指令可作为非特权指令。4C整数除零会引发异常，read 是系统调用，都会进入内核态；sin() 一般是用户态库函数调用。5C信号量为负时，其绝对值表示等待该资源的进程数，-2 表示 2 个进程等待。6A终止进程时一定要回收自身资源并撤销 PCB，但子进程不一定被终止，也可能被托管或重新挂接。7B最优安排可为：P1 计算 0-60，I/O 60-140；P2 计算 60-180；P1 计算 180-200；P2 I/O 180-220，计算 220-260，共 260ms。8A两程序并发时总时间至少不能小于最长单个程序 30s，所以 20s 不可能。9A中断或异常发生前 CPU 可能处于用户态；进入中断/异常处理程序后才处于内核态。10D时钟中断、控制台中断来自 CPU 外部；访管中断和缺页中断属于内部中断/异常。11B严格说应是每类中断类型有一个中断向量，而不是每一次具体发生的中断事件都有独立向量。若课堂将“事件”理解为“事件类型”，本题表述有歧义。12C为每个应用单独配一个键盘驱动线程不是多线程系统的典型优势。13B线程提高进程内部并发度，有助于提高系统效率；线程不能脱离进程独立存在。14D有序资源分配通过规定资源申请顺序破坏循环等待条件。15C管程中的 signal 是对条件变量的唤醒，不等同于信号量的 V 操作。16D“根据 R 找到消息接收者”本质是找到接收进程的 PCB，再取得其接收缓冲地址等信息。17B最短寻找时间优先可能长期偏向近处请求，远处请求可能饥饿。18C分页管理的主要特点是作业不必装入主存连续区域。19A界地址管理只需基址/限长等简单硬件支持，代价最低。20DCPU 利用率低而交换磁盘利用率极高，是颠簸迹象；增加物理内存能改善。21A通道是独立于 CPU、专门负责 I/O 传输的处理单元。22A缓冲主要为缓和速度不匹配、减少中断和 I/O 次数；设备独立性不是引入缓冲的主要原因。23D工作集大小是指定窗口内访问过的不同页面数。24A每个索引块含 1KB/4B=256 个盘块号，两级索引可寻址 256*256 个数据块，即 64MB。25A删除文件会删目录项、文件控制块并释放相关缓冲/空间，但不应删除该文件所在目录本身。26C进程因 I/O 等待时处理机可被其他进程抢占，但它仍占有相关临界资源，其他进程不能进入相关临界区。27B用户 I/O 请求流程：用户程序 -> 系统调用处理程序 -> 设备驱动程序 -> 中断处理程序。28B缓冲解决传输速度不匹配；缓存提高重复访问速度。29BSPOOLing 的核心是把独占设备的操作转移到高速共享设备如磁盘上排队完成。30C虚拟段页式兼有段、页优点，但实现复杂、系统开销大。二、简答题1. 死锁与饿死的相同点和不同点相同点：都会导致某些进程长期不能向前推进。都与资源分配、调度策略或同步机制有关。都可能表现为进程长时间等待资源或处理机。不同点：死锁是多个进程形成相互等待关系，例如 P1 等 P2 的资源，P2 又等 P1 的资源，通常需要外部干预才能打破。饿死是某个进程长期得不到资源或处理机，原因常是调度/分配策略不公平，例如高优先级进程不断到来、SSTF 长期服务近处磁道。死锁进程集合中的进程通常都处于阻塞等待状态；饿死进程未必一直阻塞，也可能反复进入就绪队列但总是选不上。死锁强调循环等待等 Coffman 条件；饿死强调等待时间无上界和公平性不足。2. 磁头粘性“磁头粘性”指磁盘调度中，如果新请求不断加入当前扫描队列，尤其集中在当前磁头附近或当前扫描方向上，磁头可能不断服务这些新来的近处请求，迟迟离不开某一区域，使远处请求长时间等待。如果每个磁道各有一个磁头，则不存在移动磁头在磁道之间来回移动的问题，也就不存在原意义上的“磁头粘性”。仍可能有请求队列公平性问题，但不是由移动磁头调度造成的粘性。3. test_and_set 算法的有限等待问题与改进原算法：do { while (test_and_set(&lock)) continue; 临界区; lock = 0; 其余部分; } while (1);不满足有限等待的原因：当某进程离开临界区并把 lock 置 0 后，所有等待进程和新来的进程同时竞争 test_and_set。某个等待已久的进程可能反复竞争…

『操作系统』期末复习
type: item
date: 2026-05-25T17:10:00+08:00
description: 本文页码均指课件页码操作系统概述一、核心主线操作系统是位于硬件之上、其他软件之下的系统软件，它负责管理计算机软硬件资源，并为用户和应用程序提供方便、安全、高效的服务。也就是说，操作系统既是：资源管理者：管理 CPU、内存、设备、文件等资源。 用户接口：提供命令行、图形界面、系统调用等使用方式。 虚拟机：把复杂硬件包装成更易用的逻辑资源，比如虚拟 CPU、虚拟内存、虚拟设备。 控制程序：通过中断、调度、保护机制控制程序运行。二、操作系统的概念1. 操作系统的地位课件中强调：操作系统位于 硬件层 HAL 之上，位于 其他系统软件和应用软件之下。可以理解成：应用软件 系统软件 / 系统库 操作系统 硬件 / HAL应用程序通常不会直接操作硬件，而是通过 库函数 或 系统调用 请求操作系统完成底层工作。例如：printf("Hello");表面上是 C 语言函数，实际上最终要通过操作系统完成显示设备或终端输出。2. 操作系统的作用主要有两类：第一，管理资源：资源操作系统做什么CPU调度多个程序运行内存分配、保护、共享、扩充设备分配设备、驱动设备、管理 I/O文件组织文件系统，支持读写、目录、权限第二，提供服务接口：包括 API、GUI、命令行、作业控制语言 JCL 等。3. 操作系统定义课件中的定义可以背下来：操作系统是位于硬件层之上、所有其他软件层之下的系统软件，通过它管理系统中各种软硬件资源，使它们被充分利用，并方便用户使用计算机系统。考试中如果问“什么是操作系统”，答这个定义基本够用。三、操作系统的发展历史这一部分容易考“发展阶段”和“各阶段特点”。1. 手工操作阶段时间大约是 20 世纪 40 年代，无操作系统。特点：程序员手工操作机器； 使用纸带、卡片、开关、接线板； CPU 经常等待人操作，效率极低； 资源被一个作业独占。重点理解：机器越来越快后，人工操作时间反而成了主要瓶颈。2. 批处理阶段为了解决人工干预太多的问题，出现批处理。分为：联机批处理：作业从读卡机进入计算机，按批处理执行。优点是减少人工干预，缺点是 I/O 慢，主机等待时间长。脱机批处理：使用卫星机完成输入输出转换，主机专心计算。优点是减少主机等待 I/O，缺点是需要人工搬磁带和额外设备。3. 执行系统阶段出现了 通道 和 中断 技术。通道可以理解为专门负责 I/O 的处理机，它接受 CPU 委托执行 I/O 操作。这样 CPU 和 I/O 可以并行工作。这一阶段出现了 SPOOLing 假脱机技术。4. 多道批处理系统这是操作系统走向成熟的重要标志。核心思想：内存中同时放入多个作业，当一个作业等待 I/O 时，CPU 可以去执行另一个作业。优点：提高 CPU 利用率； 提高系统吞吐量； 适合大型科学计算任务。但它也带来了一系列新问题：互斥、同步、通信、死锁、饥饿等。这些正是后面几章重点内容。5. 分时系统分时系统面向交互式用户。特点：多用户通过终端连接主机； 系统轮流给每个用户分配 CPU 时间片； 用户感觉自己独占一台机器。典型系统：CTSS、Multics、UNIX。6. 实时系统实时系统强调 及时响应 和 高可靠性。应用场景：工业控制、军事控制、医疗控制、航班订票、联机检索等。重点：实时系统不是单纯追求“快”，而是要求 在规定时间内完成响应。7. 通用操作系统通用操作系统把批处理、分时、实时等功能结合起来。常见模式：前台分时 + 后台批处理； 前台实时 + 后台批处理。四、操作系统的四大特性这部分常考简答题。1. 并发性多个程序在宏观上同时向前推进。注意区分：概念含义并发宏观同时，微观交替并行真正同时，需要多个处理器或多个核心单 CPU 上可以有并发，但不能真正并行执行多个程序。2. 共享性多个程序共同使用系统资源。例如：多个程序共享 CPU； 多个进程共享内存中的某些区域； 多个用户共享打印机； 多个进程共享文件。共享必须由操作系统协调，否则会产生冲突。3. 异步性程序推进速度不可预知。原因是：多个程序交替运行； 中断随机发生； 调度时机不确定。所以程序执行顺序并不完全由程序员控制，而受中断、调度、资源状态影响。4. 虚拟性通过某种技术把一个物理实体变成多个逻辑实体。例子：物理实体虚拟效果一个 CPU多个虚拟 CPU内存 + 外存更大的虚拟存储空间独占设备可共享的虚拟设备这一点非常重要，后面虚拟存储、虚拟设备都会继续展开。五、操作系统的主要类型1. 多道批处理系统关键词：多道、成批、吞吐量、资源利用率。适合非交互、大批量计算任务。重点概念：SPOOLing。SPOOLing 又叫假脱机技术或排队转储技术，由输入井、输出井和常驻 I/O 进程组成。它可以把独占设备改造成共享设备，实现虚拟设备功能。2. 分时操作系统关键词：多路性、交互性、独占性。多路…

Good First Issue 指南
type: item
date: 2026-05-11T22:00:00+08:00
description: Good First IssueGood = 友好的、适合新手的 First = 给第一次做开源贡献的人 good-first-issue ： 适合新手第一次贡献的优质入门任务。它是开源社区吸引新成员、降低入门门槛的重要机制，也是开启开源贡献之旅的最佳起点。声明这里首先演示 HTTPS 方式master / main 请根据实际情况选择不同环境或系统的命令不一定相同，本文仅作为参考。基础准备环境配置# 安装 git、vim sudo dnf install -y git vim git-lfs # 配置Git全局信息（与 AtomGit/GitHub 账号一致） git config --global user.name "用户名" git config --global user.email "注册邮箱" # 查看配置是否生效 git config --list 访问令牌在个人设置→安全设置之类的地方找到访问令牌，生成新令牌（勾选 repo 权限），复制并保存生成的令牌字符串（该字符串只显示一次，务必保存好）ForkFork 相当于「把官方仓库复制一份到自己的账号下」，是参与项目的第一步。 页面右上角的 Fork 按钮，选择 Fork 到自己的账号下。Clone克隆 = 「把远程仓库下载到本地」，必须克隆「自己 Fork 后的仓库」，而非官方仓库。打开本地终端；进入想存放代码的文件夹（比如 cd ~/code，表示进入用户目录下的 code 文件夹）；执行克隆命令（替换成自己 Fork 后的仓库地址）git clone https://******.git 进入克隆后的仓库目录cd 仓库名配置上游官方仓库（该动作仅需 1 次）目的是让本地仓库「知道官方仓库的地址」，方便后续同步。确保终端在仓库目录下（已执行 cd 仓库名 ）；执行添加命令git remote add upstream 官方仓库地址验证是否添加成功git remote -v 正常的输出大概是： origin https://***.com/我的账号/***.git (fetch) origin https://***.com/我的账号/***.git (push) upstream https://***.com/官方账号/***.git (fetch) upstream https://***.com/官方账号/***.git (push)同步官方仓库的最新代码官方仓库会不断更新，每次本地开发前，先同步上游代码，避免本地的修改和官方代码冲突。确保当前在仓库根目录；拉取官方仓库的最新代码（只下载，不修改本地文件）git fetch upstream 切换到本地主分支（master/main）git checkout master合并官方最新代码到本地主分支（最终同步）git merge upstream/master验证同步成功git log --oneline # 同步上游代码后，验证本地是否是官方最新版 创建并切换到开发分支严禁在主分支（master/main）修改代码，因为这会导致代码混乱。 所以需要新建一个专属分支用来修改/更新，任务完成后直接提交这个分支即可。分支命名规范格式：issue-编号-简单描述示例：修复文档：issue-1234-fix-docs修复错别字：issue-5678-fix-typo完善注释：issue-9012-add-commentIssue 数字编号方便之后关联任务创建 + 切换分支git checkout -b issue-1234-fix-docs checkout：切换分支-b：create branch（创建新分支）自定义分支名# 分开的命令 git branch 分支名 # 创建分支 git checkout 分支名 # 切换分支验证分支切换成功 执行命令查看当前所在分支：git branch 示例效果：* issue-1234-fix-docs # 前面带*的分支，就是当前正在使用的开发分支 master 开发# 打开需要修改的文件（根据Issue要求，例：修改README.md） vim README.md # Vim 基础操作（新手必看） # 按 i → 进入编辑模式 # 修改内容（修复错别字、补全注释、调整格式等） # 按 Esc → 退出编辑模式 # 输入 :wq → 保存并退出 # 输入 :q! → 不保存退出（放弃修改） # 查看修改内容（确认修改正确） git diff 提交与推送当我们完成本地开发后，需要把修改推到自己 Fork 的仓库（ origin 仓库）。# 1. 添加修改的文件到暂存区 git add 文件名 # 例：git add README.md # 或 git add . （添加…

Verilog 学习笔记（14）：More Circuits
type: item
date: 2025-07-26T23:50:00+08:00
description: Rule 90.数组的异或规则是对应分量两两异或，得到一个新的数组。 Solutionmodule top_module( input clk, input load, input [511:0] data, output [511:0] q ); always @(posedge clk) begin if (load) //别忘了先加载 q <= data; else q <= {1'b0,q[511:1]} ^ {q[510:0],1'b0}; end endmodule Rule 110将左、中、右状态组合为 3 位索引，查表（Rule 110 的转移表）得到下一状态。将左、中、右分别作为三个变量（含有512个分量的数组），作卡诺图：L\C R000111100011110101于是，$C^{(n+1)} = \bar{C}R +\bar{L}C+C\bar{R}$ Solutionmodule top_module( input clk, input load, input [511:0] data, output [511:0] q ); wire [511:0] L,C,R; assign L = {1'b0,q[511:1]}; assign C = q; assign R = {q[510:0],1'b0}; always @(posedge clk) begin if(load) q <= data; else q <= (~C & R) | (~L & C) | (C & ~R); end endmodule Conway's Game of Life 16x16题意生命游戏是二维元胞自动机，每个细胞（cell）状态为1（活）或0（死），下一状态由8 个邻居的存活数决定：邻居存活数细胞下一状态0-1 个死亡（变 0）2 个保持当前状态3 个复活（变 1，即使之前是死的）≥4 个死亡（变 0）索引转换由一维索引转换到二维索引：行号 i：用idx 除以 16取整（舍去余数）；等效于： idx >> 4（右移 4 位 = 除以 2⁴）。列号 j：j = idx % 16（取模运算，即余数）；等效于按位与：idx & 15（15 的二进制是 1111，按位与之后达到保留低 4 位（即余数）的效果）。由二维索引转换到一维索引： (i, j) 的一维索引为 i * 16 + j.右移位运算符>> 是 右移位运算符：逻辑右移（>>）将二进制数向右移动，左侧空出的位用 0 填充，不考虑符号位。 语法：A >> N（将 A 右移 N 位）。算术右移（>>>）将二进制数向右移动，左侧空出的位用符号位填充（即保持负数的符号）。 语法：A >>> N（将 A 右移 N 位）。Solutionmodule top_module( input clk, input load, input [255:0] data, output [255:0] q ); reg [255:0] q_reg; // 模块级寄存器存储当前状态 assign q = q_reg; // 输出直接映射到寄存器 always @(posedge clk) begin // ------- 步骤1：声明过程块内的变量（必须放在块的开头）--------- reg [255:0] next_q; //存储下一状态（局部reg） integer idx; //当前细胞的一维索引 integer dr; //相对于当前细胞的行偏移（Delta Row） integer dc; //相对于当前细胞的列偏移（Delta Column） integer i; //当前细胞的二维行索引 integer j; //当前细胞的二维列索引 integer r; //邻居的绝对坐标的行索引 integer c; //邻居的绝对坐标的列索引 integer neighbor_idx; //邻居的一维索引 integer cnt; //邻居的存活数目 if (load) begin // 加载模式：直接赋值 q_reg <= data; end else begin // --------- 步骤2：遍历每个细胞，计算下一状态 ------------ for (idx = 0; idx < 256; idx = idx + 1) begin i = idx >> 4; // 计算当前细胞的行号（0~15） j = idx & 15; // 计算当前细胞的列号（0~15） cnt = 0; // 邻居存活数初始化 // 遍历8个邻居（dr, dc ∈ {-1, 0, 1}，左右位移只能取1或-1，所以待会需要跳过自身） for (dr = -1; dr <= 1; dr = dr + …

Verilog 学习笔记（13）：Shift Registers
type: item
date: 2025-07-26T09:40:00+08:00
description: 4-bit shift register异步复位的优先级：areset为高时，立即复位（不管时钟和其他信号）。加载 vs 移位的优先级：若load为 1，无论和ena为何值，加载优先（先判断load）。右移操作的行为：右移时，q[3]补 0，q[0]被移出（例如：q=1010右移后变为0101）。Solutionmodule top_module( input clk, input areset, // async active-high reset to zero input load, input ena, input [3:0] data, output reg [3:0] q); always @(posedge clk or posedge areset) begin if (areset) begin q <= 4'b0000; end else begin if (load) begin q <= data; end else if(ena) begin q <= {1'b0,q[3:1]}; end end end endmodule Left/right rotatorSolutionmodule top_module( input clk, input load, input [1:0] ena, input [99:0] data, output reg [99:0] q); always @(posedge clk) begin if (load) // load q <= data; else if (ena) begin case(ena) 2'b00 : q <= q; // 其实这一行永远不会被执行！所以else分支可以被简化，见下方。 2'b01 : q <= {q[0],q[99:1]}; // 右旋转 （采用分块组合要比使用循环更简便） 2'b10 : q <= {q[98:0],q[99]};// 左旋转 2'b11 : q <= q; default q <= q; endcase end else begin // 当ena为0时执行 保持不变 q <= q; end end endmodule 简化else之后：always @(posedge clk) begin if (load) q <= data; else if (ena == 2'b01) q <= {q[0],q[99:1]}; // 右旋转 else if (ena == 2'b10) q <= {q[98:0],q[99]}; // 左旋转 // 其他情况（ena=2'b00或2'b11）保持不变 endLeft/right arithmetic shift by 1 or 8A 5-bit number 11000 arithmetic right-shifted by 1 is 11100, while a logical right shift would produce 01100. However, there is no difference between logical and arithmetic left shifts. Solutionmodule top_module( input clk, input load, input ena, input [1:0] amount, input [63:0] data, output reg [63:0] q); always @(posedge clk) begin if (load) begin q <= data; end else if (ena) begin case (amount) 2'b00: q <= {q[62:0],1'b0}; 2'b01: q <= {q[55:0],8'b0}; 2'b10: q <= {q[63],q[63:1]}; 2'b11: q <= {{8{q[63]}},q[63:8]}; //注意：位拼接语法 default: q <= q; endcase end end endmodule 5-bit LFSR线性反馈移位寄存器（LFSR） linear feedback shift register LFSR 是一种通过移位寄存器和反馈逻辑生成伪随机序列的电路。 Galois 型 LFSR 的特点：反馈逻辑通过 异或（XOR） 连接特定 “抽头”（tap）位，生成下一个状态的最低位（或最高位，依结构而定）。最大长度 LFSR（maximal-length）的抽头位置经过精心选择，可遍历 $2^n-1$ 个状态（n为位数，全零状态永远不会出现）。在本题中：位数：5 位（输出q[4:0]，q[4]是最高…

Verilog 学习笔记（12）：Counters
type: item
date: 2025-07-25T08:00:00+08:00
description: Four-bit binary counterSolutionmodule top_module ( input clk, input reset, // Synchronous active-high reset output [3:0] q); always @(posedge clk) begin if(reset == 1) q <= 4'b0000; else if(q == 4'b1111) q <= 4'b0000; else q <= q + 1; end endmodule Decade counterSolutionmodule top_module ( input clk, input reset, // Synchronous active-high reset output [3:0] q); always @(posedge clk) begin if(reset == 1) q <= 4'b0000; else if(q == 4'b1001) q <= 4'b0000; else q <= q + 1; end endmodule Decade counter againSolutionmodule top_module ( input clk, input reset, output [3:0] q); always @(posedge clk) begin if(reset == 1) q <= 4'b0001; else if(q == 4'b1010) q <= 4'b0001; else q <= q + 1; end endmodule Slow decade counter暂停功能：仅当 slowena 为高电平时，计数器才会在时钟上升沿递增；否则保持当前值。 Solutionmodule top_module ( input clk, input slowena, input reset, output [3:0] q); always @(posedge clk) begin if(reset == 1) q <= 4'd0; else if(slowena) begin if(q == 4'd9) q <= 4'd0; else q = q + 1; end else q <= q; end endmodule Counter 1-12同步复位：reset 高电平时，时钟上升沿将计数器同步复位到 1。使能控制：enable 高电平时，计数器运行（计数）；enable 低电平时，计数器保持当前值（暂停）。**load 的核心作用:- **立即覆盖当前值**：当 `load=1` 时，无论计数器当前状态如何，都会在下一个时钟上升沿将 `d` 端口的值加载到计数器输出 `Q`。 - **优先级高于 `enable`**：即使 `enable=0`（计数器暂停），只要 `load=1`，计数器仍会加载 `d` 的值。 计数器的四种状态：loadenable计数器行为1X加载 d 的值（例如复位到 1 或回绕到 1）01正常计数（Q = Q + 1）00保持当前值（暂停）10仍加载 d 的值（load 优先级更高）已知：module count4( input clk, input enable, input load, input [3:0] d, output reg [3:0] Q ); Solutionmodule top_module ( input clk, input reset, input enable, output [3:0] Q, output c_enable, output c_load, output [3:0] c_d ); assign c_enable = enable; assign c_load = reset | (Q == 4'd12 && enable); assign c_d = c_load ? 4'b1 : 4'b0; count4 the_counter ( .clk(clk), .enable(c_enable), .load(c_load), .d(c_d), .Q(Q) ); endmoduleCounter 1000题中给出了一个十进制的模块，所以需要使用三次以达到把1000Hz降到1Hz. 已知：module bcdcount ( input clk, input reset, input enable, output reg [3:0] Q );Solutionmodule top_module ( input clk, input reset, output OneHertz, output [2:0] c_enabl…

Verilog 学习笔记（11）：Latches and Flip-Flops
type: item
date: 2025-07-24T14:30:00+08:00
description: D flip-flopClocked always blocks should use non-blocking assignments: <=.Solutionmodule top_module ( input clk, // Clocks are used in sequential circuits input d, output reg q );// // Use a clocked always block // copy d to q at every positive edge of clk always @(posedge clk) begin q <= d; end endmodule D flip-flopsSolutionmodule top_module ( input clk, input [7:0] d, output [7:0] q ); always @(posedge clk) begin q <= d; end endmoduleDFF with resetSolutionmodule top_module ( input clk, input reset, // Synchronous reset input [7:0] d, output [7:0] q ); always @(posedge clk) begin if (reset) begin //复位 q <= 8'b0; end else begin q <= d; end end endmodule DFF with reset value正触发: posedge 负触发: negedgeSolutionmodule top_module ( input clk, input reset, input [7:0] d, output [7:0] q ); always @(negedge clk) begin if (reset) begin q <= 8'h34; end else begin q <= d; end end endmodule DDF with asynchronous reset异步复位The only difference in code between synchronous and asynchronous reset flip-flops is in the sensitivity list——将复位信号写入敏感列表中。 Solutionmodule top_module ( input clk, input areset, // active high asynchronous reset input [7:0] d, output [7:0] q ); always @(posedge clk, posedge areset) begin if (areset) q <= 0; else q <= d; end endmodule DFF with byte enablewire vs. reg特性wirereg存储功能无存储功能，数值由驱动源决定有存储功能，能保持当前值直至下一次赋值赋值方式只能使用连续赋值（如assign语句）只能在initial或always块内赋值使用场景用于连线、组合逻辑输出用于时序逻辑（如触发器）、组合逻辑中的中间变量默认初始值默认值为z（高阻态）默认值为x（未知状态）下面通过两段代码示例，直观展示wire和reg的使用差异：// wire的使用示例 module wire_example; reg a, b; // 输入信号定义为reg类型 wire out; // 输出信号定义为wire类型 // 连续赋值，out的值会随着a和b的变化而立即改变 assign out = a & b; initial begin a = 1'b0; b = 1'b0; #10 a = 1'b1; #10 b = 1'b1; end endmodule// reg的使用示例 module reg_example; reg clk, rst, in; reg out; // 输出信号定义为reg类型，因为在always块中被赋值 // 时序逻辑：在时钟上升沿更新out的值 always @(posedge clk or posedge rst) begin if (rst) begin out <= 1'b0; // 复位时将out置为0 end else begin out <= in; // 时钟上升沿时将in的值赋给out end end initial begin clk = 1'b0; forever #5 clk = ~clk; // 生成周期为10的时钟信号 end …

Verilog 学习笔记（9）：Arithmetic Circuits
type: item
date: 2025-07-16T18:00:00+08:00
description: Half adderSolutionmodule top_module( input a, b, output cout, sum ); assign cout = a & b; assign sum = a ^ b; endmodule A half adder adds two bits (with no carry-in) and produces a sum and a carry-out.Full adderSolutionmodule top_module( input a, b, cin, output cout, sum ); assign sum = a ^ b ^ cin; assign cout = (a & b) | (a & cin) | (b & cin); endmodule 3-bit binary adder三位加法器需 3 个全加器级联，将低位的进位输出连接到高位的进位输入，形成进位链。 Solutionmodule top_module( input [2:0] a, b, input cin, output [2:0] cout, output [2:0] sum ); assign sum[0] = a[0] ^ b[0] ^ cin; assign cout[0] = (a[0] & b[0]) | (b[0] & cin) | (a[0] & cin); assign sum[1] = a[1] ^ b[1] ^ cout[0]; assign cout[1] = (a[1] & b[1]) | (b[1] & cout[0]) | (a[1] & cout[0]); assign sum[2] = a[2] ^ b[2] ^ cout[1]; assign cout[2] = (a[2] & b[2]) | (b[2] & cout[1]) | (a[2] & cout[1]); endmodule AdderSolutionmodule top_module ( input [3:0] x, input [3:0] y, output [4:0] sum); wire cout0,cout1,cout2; FullAdder FA1 (x[0],y[0],1'b0,cout0,sum[0]); FullAdder FA2 (x[1],y[1],cout0,cout1,sum[1]); FullAdder FA3 (x[2],y[2],cout1,cout2,sum[2]); FullAdder FA4 (x[3],y[3],cout2,sum[4],sum[3]); endmodule //直接用一下全加器 module FullAdder( input a, b, cin, output cout, sum ); assign sum = a ^ b ^ cin; assign cout = (a & b) | (a & cin) | (b & cin); endmoduleSigned addition overflowA signed overflow occurs when adding two positive numbers produces a negative result, or adding two negative numbers produces a positive result.In addition，正数和负数相加时，因和的范围天然被补码覆盖，故无需判断溢出，必然无溢出。 BTW：// 加法运算 wire [7:0] sum = a + b; // 执行数值相加，考虑进位 // 按位与操作 wire [7:0] and_result = a & b; // 逐位AND，不考虑进位Solutionmodule top_module ( input [7:0] a, input [7:0] b, output [7:0] s, output overflow ); // assign s = ... // assign overflow = ... assign s = a + b; //仅需要考虑最高位（符号位）即可 assign overflow = (a[7] && b[7] && ~s[7] ) || (~a[7] && ~b[7] && s[7]); endmodule 100-bit binary adderSolutionmodule top_module( input [99:0] a, b, input cin, output cout, output [99:0] sum ); //assign sum = a ^ b ^ cin;…

Verilog 学习笔记（8）：Multiplexers
type: item
date: 2025-07-14T16:50:00+08:00
description: 2-to-1 multiplexerSolutionmodule top_module( input a, b, sel, output out ); assign out = sel ? b : a; endmodule 2-to-1 bus multiplexerSolutionmodule top_module( input [99:0] a, b, input sel, output [99:0] out ); assign out = sel ? b : a; //每一位允许自动匹配 endmodule 9-to-1 multiplexerSolutionmodule top_module( input [15:0] a, b, c, d, e, f, g, h, i, input [3:0] sel, output [15:0] out ); always @(*) begin case (sel) 4'b0000:out = a; 4'b0001:out = b; 4'b0010:out = c; 4'b0011:out = d; 4'b0100:out = e; 4'b0101:out = f; 4'b0110:out = g; 4'b0111:out = h; 4'b1000:out = i; //default:out = 1; //在输出端口16位宽的的时候不能直接写1 default: out = 16'hFFFF; // 设置默认值为全1 （16进制） endcase end endmodule 256-to-1 multiplexerVector indices can be variable, as long as the synthesizer can figure out that the width of the bits being selected is constant. In particular, selecting one bit out of a vector using a variable index will work. Solutionmodule top_module( input [255:0] in, input [7:0] sel, output out ); assign out = in[sel]; endmodule 256-to-1 4-bit multiplexerSolutionmodule top_module( input [1023:0] in, input [7:0] sel, output [3:0] out ); assign out = {in[4*sel+3],in[4*sel+2],in[4*sel+1],in[4*sel]}; //注意顺序应该是从高位到低位 endmodule

Verilog 学习笔记（7）：Basic Gates
type: item
date: 2025-07-12T20:50:00+08:00
description: 本节是一些练习巩固的习题。WireSolutionmodule top_module ( input in, output out); assign out = in; endmoduleGNDGND（Ground）： “地线” 或 “接地”。Solutionmodule top_module ( output out); assign out = 1'b0; endmoduleNORSolutionmodule top_module ( input in1, input in2, output out); assign out = ~(in1 | in2); //注意别忘了“非” endmoduleAnother gateSolutionmodule top_module ( input in1, input in2, output out); assign out = in1 & ~in2; endmoduleTwo gatesSolutionmodule top_module ( input in1, input in2, input in3, output out); wire m1; assign m1 = ~(in1 ^ in2); assign out = m1 ^ in3; endmoduleMore logic gatesSolutionmodule top_module( input a, b, output out_and, output out_or, output out_xor, output out_nand, output out_nor, output out_xnor, output out_anotb ); assign out_and = a & b; assign out_or = a | b; assign out_xor = a ^ b; //异或 assign out_nand = ~(a & b); assign out_nor = ~(a | b); assign out_xnor = ~(a ^ b); //同或 assign out_anotb = a & ~b; //a 和 非b endmodule7420 chipSolutionmodule top_module ( input p1a, p1b, p1c, p1d, output p1y, input p2a, p2b, p2c, p2d, output p2y ); assign p1y = ~(p1a & p1b & p1c & p1d); assign p2y = ~(p2a & p2b & p2c & p2d); endmoduleTruth tablesOne simple method to create a circuit that implements the truth table's function is to express the function in sum-of-products form. Sum (meaning OR) of products (meaning AND) means using one N-input AND gate per row of the truth table (to detect when the input matches each row), followed by an OR gate that chooses only those rows that result in a '1' output. 总结：推导 sum-of-products (SOP，积之和)的核心逻辑：用最小项 “标记” 所有输出为 1 的输入组合，再用 OR 运算 “汇总” 这些有效组合。由于最小项仅在唯一输入组合下为 1，OR 之后的表达式能精准复现真值表的输出逻辑。“找 1 行，写反 / 原变量乘积，再 OR”。 Solutionmodule top_module( input x3, input x2, input x1, // three inputs output f // one output ); assign f = (~x3 & x2 & ~x1) | (~x3 & x2 & x1) | (x3 & ~x2 & x1) | (x3 & x2 & x1); endmoduleTwo-bit equality通过直接比较两个 2 位输入 A 和 B 来判断它们是否相等，采用了 Verilog 的条件赋值语句即可。 Solutionmodule top_module ( input [1:0] A, input [1:0] B, output z ); as…