diff --git a/public/doc/01_water_led/images/1.png b/public/doc/01_water_led/images/1.png
new file mode 100644
index 0000000..45094e0
Binary files /dev/null and b/public/doc/01_water_led/images/1.png differ
diff --git a/public/doc/01_water_led/images/2.png b/public/doc/01_water_led/images/2.png
new file mode 100644
index 0000000..118cb90
Binary files /dev/null and b/public/doc/01_water_led/images/2.png differ
diff --git a/public/doc/01_water_led/images/3.png b/public/doc/01_water_led/images/3.png
new file mode 100644
index 0000000..49520aa
Binary files /dev/null and b/public/doc/01_water_led/images/3.png differ
diff --git a/public/doc/01_water_led/images/4.png b/public/doc/01_water_led/images/4.png
new file mode 100644
index 0000000..a9134bb
Binary files /dev/null and b/public/doc/01_water_led/images/4.png differ
diff --git a/public/doc/01_water_led/water_led.md b/public/doc/01_water_led/water_led.md
new file mode 100644
index 0000000..f0f0496
--- /dev/null
+++ b/public/doc/01_water_led/water_led.md
@@ -0,0 +1,175 @@
+# 基础-1-流水灯
+
+## 1.1 章节导读
+
+流水灯实验作为基础实验的第一个实验是非常合适的,本章我们利用试验箱中的LED进行点亮LED,并实现流水灯的功能。
+
+## 1.2 理论学习
+
+相信大家之前肯定接触过单片机等设备,而学习这些设备的第一个实验例程往往都是点亮一个LED。本次实验在点亮LED的基础上另LED灯依次闪亮,循环不止,实现“流水”的功能。其原理是依次控制连接到LED的IO口的电平高低,让LED的闪亮间隔为0.5s,以实现流水灯的效果。
+
+## 1.3 实战演练
+
+### 1.3.1实验目标
+
+依次点亮实验板中的8个LED灯,两灯点亮间隔为0.5s,每次点亮持续0.5s,实现流水灯效果。
+
+### 1.3.2硬件资源
+
+实验板上有0~31共32个LED灯的资源,每4个LED灯为一组,分别是绿,红,蓝,黄四种颜色,本次实验使用8个LED进行验证。
+
+
+
+
+
+ 图1.LED扩展板
+
+
+
+通过原理图可以得知,本试验箱的LED灯为高电平时点亮。
+
+
+
+
+
+ 图2.LED扩展板原理图
+
+
+
+### 1.3.3程序设计
+
+流水灯的设计与分频器,计数器的逻辑相似,只是多了LED灯的点亮部分。为了实现计数器肯定需要时钟信号sysclk,也需要一个复位信号rstn,同时为了驱动LED,需要8个IO口。所以模块的端口如下表所示:
+
+| 端口名称 | 端口位宽 | 端口类型 |功能描述
+|:----------:|:----:|:----:|:--------------------:|
+| sysclk | 1Bit | Input | 输入时钟,频率27M |
+| rstn | 1Bit | Input | 复位信号,低电平有效 |
+| led | 8Bit | Output | LED控制信号 |
+
+
+为了使灯点亮0.5s,我们应该设计一个计数器或者是分频器,先将板载27M高频时钟降速。在27M时钟下计数0.5s,需要计数器计数13_500_000个数,也就是计数器从0开始计数到13_499_999。所以我们定义一个寄存器cnt,每一次时钟上升沿cnt就加1,当计数到13_499_999时,led的状态改变,同时cnt归零重新开始计数。
+
+为了实现8个led流水的效果,我们将0定义为led灭,1表示亮,初始状态led = 8’b0000_0001,当经过0.5s后,也就是cnt等于13_499_999的时候,第一个led灭,第二个led亮起,也就是led = 8‘b0000_0010。同理,再过0.5s,led = 8’b0000_0100,再过0.5s,led = 8‘b0000_1000以此类推。
+
+根据上面的规律我们很容易发现,led的流水是靠1的移位来实现的,也就是最基本的左移(<<)和右移(>>)运算符去实现。在这里我们需要向左移位,并且每次只需要移动1位。模块的参考代码(waterled_top.v)如下所示:
+
+```verilog
+module waterled_top(
+ input sysclk, //27MHz system clock
+ input rstn, //active low reset
+ output [7:0] led
+ );
+ parameter CNT_MAX = 32'd13_499_999;
+ reg [7:0] led_reg;
+ reg [31:0] cnt;
+ //cnt 当cnt == CNT_MAX时变为0,计数0.5秒
+ always @(posedge sysclk) begin
+ if (!rstn)
+ cnt <= 0;
+ else if (cnt < CNT_MAX)
+ cnt <= cnt + 1;
+ else
+ cnt <= 0;
+ end
+ //led_reg 当cnt == CNT_MAX时,左移一位。
+ always @(posedge sysclk) begin
+ if (!rstn)
+ led_reg <= 8'b0000_0001;
+ else if (led_reg == 8'b1000_0000 && cnt == CNT_MAX)//led7亮0.5s后重回led0
+ led_reg <= 8'b0000_0001;
+ else if (cnt == CNT_MAX) //0.5s后左移
+ led_reg <= led_reg << 1;
+ else
+ led_reg <= led_reg;
+ end
+ //led
+ assign led = led_reg;
+endmodule
+```
+
+### 1.3.4仿真验证
+
+为上述模块编写仿真模块,参考代码(waterled_top_tb.v)如下:
+
+```verilog
+`timescale 1ns/1ns
+module waterled_top_tb;
+
+ reg sysclk;
+ reg rstn;
+ wire [7:0] led;
+
+ // 实例化待测试模块
+ waterled_top #(
+ .CNT_MAX(32'd100)//为了加快仿真速度,将模块内部CNT_MAX由13_499_999变为1000
+ )uut (
+ .sysclk(sysclk),
+ .rstn(rstn),
+ .led(led)
+ );
+ // 产生系统时钟:周期约为 27Mhz
+ initial begin
+ sysclk = 0;
+ forever #(500/27) sysclk = ~sysclk;
+ end
+ // 初始化和复位过程
+ initial begin
+ // 初始化
+ rstn = 0;
+ #100; // 保持复位100ns
+ rstn = 1; // 释放复位
+ end
+endmodule
+```
+
+为了加速仿真,我们在仿真文件中另CNT_MAX的值为100。同时为了便于仿真,可以直接点击sim文件夹下hebav文件夹中的do.bat文件即可利用ModuleSim对模块进行仿真,仿真波形如下:
+
+
+
+
+
+ 图3.流水灯仿真波形(一)
+
+
+
+
+
+
+
+ 图4.流水灯仿真波形(二)
+
+
+
+从图3我们可以看到,端口信号led的值经过一定时间之后就进行了左移,并且在图4中我们也可以发现,当cnt的值等于CNT_MAX的时候led进行左移,与我们设计的目标相符合,可以进行下一步上板验证了。
+
+### 1.3.5上板验证
+
+仿真已经通过,可以进行上板验证,上板前要先进行管脚约束。端口与对应管脚如下表所示:
+| 端口名称 |信号类型| 对应管脚|功能
+|:----:|:----:|:----:|:----:|
+| sysclk | Input | | 时钟 |
+| rstn | Input | | 复位 |
+| led[0] | Output | | LED |
+| led[1] | Output | | LED |
+| led[2] | Output | | LED |
+| led[3] | Output | | LED |
+| led[4] | Output | | LED |
+| led[5] | Output | | LED |
+| led[6] | Output | | LED |
+| led[7] | Output | | LED |
+
+管脚分配可以直接编写.fdc文件,也可以使用PDS内置的工具进行分配。
+
+完成管脚分配之后就可以生成sbit文件,将文件提交到网站后点击烧录,即可将sbit下载到实验板中,在摄像头页面即可观察到流水灯的现象。
+
+## 1.4 章末总结
+
+本次实验主要学习使用左移(<<)和右移(>>)运算符实现移位,但实际应用中也可以使用位拼接({})进行更加复杂的移位操作,各位同学可以尝试学习。
\ No newline at end of file
diff --git a/public/doc/02_key/images/1.png b/public/doc/02_key/images/1.png
new file mode 100644
index 0000000..a791e5c
Binary files /dev/null and b/public/doc/02_key/images/1.png differ
diff --git a/public/doc/02_key/images/2.png b/public/doc/02_key/images/2.png
new file mode 100644
index 0000000..a64ae7d
Binary files /dev/null and b/public/doc/02_key/images/2.png differ
diff --git a/public/doc/02_key/images/3.png b/public/doc/02_key/images/3.png
new file mode 100644
index 0000000..ad95a9c
Binary files /dev/null and b/public/doc/02_key/images/3.png differ
diff --git a/public/doc/02_key/images/4.png b/public/doc/02_key/images/4.png
new file mode 100644
index 0000000..e05eadb
Binary files /dev/null and b/public/doc/02_key/images/4.png differ
diff --git a/public/doc/02_key/images/5.png b/public/doc/02_key/images/5.png
new file mode 100644
index 0000000..b4f6277
Binary files /dev/null and b/public/doc/02_key/images/5.png differ
diff --git a/public/doc/02_key/images/6.png b/public/doc/02_key/images/6.png
new file mode 100644
index 0000000..8dc484d
Binary files /dev/null and b/public/doc/02_key/images/6.png differ
diff --git a/public/doc/02_key/images/7.png b/public/doc/02_key/images/7.png
new file mode 100644
index 0000000..31674a7
Binary files /dev/null and b/public/doc/02_key/images/7.png differ
diff --git a/public/doc/02_key/key.md b/public/doc/02_key/key.md
new file mode 100644
index 0000000..4b55af9
--- /dev/null
+++ b/public/doc/02_key/key.md
@@ -0,0 +1,258 @@
+# 基础-2-按键检测与消抖
+
+## 2.1 章节导读
+
+在数字电路中,按键是最常用的人机交互输入方式。然而,机械式按键在按下或释放过程中会产生抖动信号,直接读取会引起误触发。本章我们将实现一个可靠的按键检测模块,完成信号的消抖和下降沿检测,以便为更复杂的模块如状态机切换、模式转换等提供稳定的触发信号。
+
+## 2.2 理论学习
+
+由于机械结构的限制,按键在触发的一瞬间,其接触点会发生数次抖动,导致输出信号在0和1之间反复跳变。这种现象称为“抖动”。为避免系统错误响应,需要对按键信号进行“消抖”处理。
+
+常见的软件消抖方法包括定时器延时,而在软件中通常使用计数器。在本实验中,采用对输入信号进行采样判断,当其状态发生变化时开始计数,若持续稳定一定时长后,才认为按键真正改变。
+
+在此基础上,若需检测按键的“按下事件”,则还需进一步提取其上升沿(或下降沿)作为一个单周期的“有效触发”信号。
+
+## 2.3 实战演练
+
+### 2.3.1 实验目标
+
+实现一个具有消抖功能的按键检测模块,并进一步提取其下降沿触发信号,输出一个单时钟周期宽度的 `btn_flag` 信号,用于后级逻辑判断。同时为了使实验现象更加明显,设置8位的IO输出连接led,当检测到 `btn_flag` 信号后8位信号`led`会自加1。
+
+### 2.3.2 硬件资源
+
+本实验使用试验箱上普通按键输入资源,输入信号经过电平转换后进入 FPGA 芯片,输出信号可连接状态指示灯以观察效果。
+
+根据原理图可知实验板的按键按下是低电平,不按为高电平。
+
+
+
+
+
+ 图1.实验板的按键资源
+
+
+
+
+
+
+ 图2.实验板按键原理图
+
+
+
+
+
+
+
+ 图3.远程实验界面按键
+
+
+
+### 2.3.3 程序设计
+
+为了实现稳定的按键检测逻辑,设计流程如下:
+
+1. 对输入 `btn` 进行采样,形成 `btn_temp`;
+2. 若检测到 `btn_temp` 与当前 `btn` 状态不一致,则开始计数;
+3. 若计数器 `cnt` 达到设定阈值(如255),则认为按键状态稳定,更新 `btn_ggle`;
+4. 实验板的按键按下是低电平,不按为高电平。所以对 `btn_ggle` 打两拍形成 `btn_flag_d0` 和 `btn_flag_d1`,再判断其下降沿,输出一个时钟周期的`btn_flag`;
+5. 检测到信号`btn_flag`后,信号`led <= led + 1`。
+
+该模块的参考代码如下(`btn_ggle.v`):
+
+```verilog
+module btn_ggle(
+ input wire clk,
+ input wire rstn,
+ input wire btn,
+ output wire btn_flag,
+ output reg [7:0] led
+);
+reg btn_ggle;
+reg btn_flag_d0,btn_flag_d1;
+reg [7:0] cnt;
+reg btn_temp;
+//检测按键状态
+always @(posedge clk) btn_temp <= btn;
+//按键状态改变时开始计数
+always @(posedge clk) begin
+ if(~rstn) cnt <= 0;
+ else if(btn_temp != btn) cnt <= 1;
+ else if(cnt != 0) cnt <= cnt + 1;
+ else cnt <= 0;
+end
+//计数到255时认为按键值稳定
+always @(posedge clk) begin
+ if(~rstn) btn_ggle <= btn;
+ else if(cnt == 8'hFF) btn_ggle <= btn_temp;
+ else btn_ggle <= btn_ggle;
+end
+//对btn_ggle信号延迟打拍
+always @(posedge clk) begin
+ if(~rstn) begin
+ btn_flag_d0 <= 0;
+ btn_flag_d1 <= 0;
+ end
+ else begin
+ btn_flag_d0 <= btn_ggle;
+ btn_flag_d1 <= btn_flag_d0;
+ end
+end
+//btn_flag检测btn_ggle的下降沿
+assign btn_flag = ~btn_flag_d0 && btn_flag_d1;
+//检测到按键按下的标志位(btn_flag),led会加1
+always @(posedge clk) begin
+ if(~rstn) led <= 0;
+ else if(btn_flag) led <= led + 1;
+ else led <= led;
+end
+endmodule
+```
+
+### 2.3.4 仿真验证
+
+为验证功能的正确性,设计测试平台(`btn_ggle_tb.v`),代码如下:
+
+```verilog
+`timescale 1ns/1ns
+module btn_ggle_tb;
+
+reg clk;
+reg rstn;
+reg btn;
+wire btn_flag;
+wire [7:0] led;
+btn_ggle btn_ggle_inst (
+ .clk(clk),
+ .rstn(rstn),
+ .btn(btn),
+ .btn_flag(btn_flag),
+ .led(led)
+);
+
+// 27MHz 时钟周期约为 37.037ns,取37ns近似
+always #(500/27) clk = ~clk; // 半周期18.5ns ≈ 27MHz
+
+initial begin
+ // 初始化
+ clk = 0;
+ rstn = 0;
+ btn = 1; // 按键默认未按下,高电平有效
+
+ // 释放复位
+ #200;
+ rstn = 1;
+
+ // 模拟带抖动的按下过程
+ #1000 btn = 0;
+ #100 btn = 1; // 抖动
+ #100 btn = 0;
+ #100 btn = 1;
+ #100 btn = 0;
+ // 稳定按下
+ #100000 btn = 0;
+
+ // 模拟抖动松开过程
+ #300000 btn = 1;
+ #100 btn = 0;
+ #100 btn = 1;
+ #100 btn = 0;
+ #100 btn = 1;
+ // 稳定松开
+ #100000 btn = 1;
+
+ // 第二次按下
+ #300000 btn = 0;
+ #100000 btn = 0;
+
+ #300000 $finish;
+end
+
+endmodule
+```
+
+利用ModuleSim进行仿真,部分仿真波形如下图所示:
+
+
+
+
+
+ 图4.仿真波形(一)
+
+
+
+
+
+
+
+ 图5.仿真波形(二)
+
+
+
+
+
+
+ 图6.仿真波形(三)
+
+
+
+从仿真波形二和三中,我们可以看到,当我们模拟按键按下(1 ----> 0),当按键抖动(`btn`在0和1之间来回跳转)时,`cnt`的值会变回1重新开始计数,直到按键稳定按下(`btn`的值稳定不变,为0),`cnt`稳定增加,当`cnt`的值增加到`8‘hFF`时,认为按键按下,`btn_ggle`存储此时的按键状态,同时`btn_flag`检测到下降沿,拉高一个时钟周期。`led`信号也加一。
+
+
+
+
+
+
+ 图7.仿真波形(四)
+
+
+
+
+
+
+ 图8.仿真波形(五)
+
+
+
+
+从波形三和四中,我们可以看到,当模拟按键抬起时(0 ----> 1),按键的抖动也会使`cnt`重新计数,直到稳定,`cnt`计数到`8’hFF`时,更新`btn_ggle`,由于按键是抬起,`btn_flag`不变,`led`不变。
+
+### 2.3.5 上板验证
+
+完成仿真后,可进行上板验证。端口连接如下表所示:
+
+| 端口名称 | 类型 | 管脚 |说明 |
+| -------- | ------ | ------ | ---------- |
+| clk | Input | | 27MHz 时钟 |
+| rstn | Input | | 低电平复位 |
+| btn | Input | | 外部按钮 |
+| btn_flag | Output | | 上升沿标志 |
+| led[0] | Output | | 驱动led |
+| led[1] | Output | | 驱动led |
+| led[2] | Output | | 驱动led |
+| led[3] | Output | | 驱动led |
+| led[4] | Output | | 驱动led |
+| led[5] | Output | | 驱动led |
+| led[6] | Output | | 驱动led |
+| led[7] | Output | | 驱动led |
+
+将`.sbit`文件上传至平台,并下载到实验板,多次按下按键,观察led灯跳转,如果按下1次按键led只跳转一次,那么说明达成实验目标。
+
+## 2.4 章末总结
+
+本实验通过一个典型的按键检测例子,介绍了数字系统中常用的消抖和边沿检测方法,掌握了如何利用计数器和触发器组合进行抖动抑制与事件捕捉。在更复杂的设计中,这类基础模块可作为控制逻辑的可靠触发信号源,具有广泛应用价值。
\ No newline at end of file
diff --git a/server/src/H264Encoder.cs b/server/src/H264Encoder.cs
new file mode 100644
index 0000000..e69de29
diff --git a/server/src/H264MediaSource.cs b/server/src/H264MediaSource.cs
new file mode 100644
index 0000000..e69de29
diff --git a/server/src/VideoStreamService.cs b/server/src/VideoStreamService.cs
new file mode 100644
index 0000000..e69de29
diff --git a/src/views/ProjectView.vue b/src/views/ProjectView.vue
index 204aee0..6dc81c4 100644
--- a/src/views/ProjectView.vue
+++ b/src/views/ProjectView.vue
@@ -53,159 +53,16 @@ const showDocPanel = ref(false);
const documentContent = ref('');
// 切换文档面板和属性面板
-function toggleDocPanel() {
+async function toggleDocPanel() {
showDocPanel.value = !showDocPanel.value;
// 如果切换到文档面板,则获取文档内容
if (showDocPanel.value) {
- fetchDocumentation();
+ const response = await fetch("/public/doc/01_water_led/water_led.md");
+ documentContent.value = await response.text();
}
}
-// 模拟获取文档的函数
-function fetchDocumentation() {
- // 这里模拟API请求,返回固定的Markdown内容
- const mockDocContent = `
-# FPGA WebLab 用户指南
-
-## 简介
-
-FPGA WebLab是一个基于Web的FPGA设计和实验平台,允许用户在浏览器中进行FPGA设计、仿真和验证。该平台提供了丰富的组件库和直观的界面,使FPGA学习和设计变得简单高效。
-
-## 功能特点
-
-- **可视化设计**:拖拽式界面,无需编写底层代码
-- **组件库**:包含多种常用FPGA组件
-- **实时验证**:设计完成后可立即进行验证和测试
-- **远程编程**:支持远程将设计烧录到物理FPGA设备
-- **协作功能**:支持多人同时在线编辑和查看
-
-## 快速入门
-
-### 创建项目
-
-1. 点击主界面的"新建项目"按钮
-2. 输入项目名称和描述
-3. 选择目标FPGA设备型号
-4. 点击"创建"完成项目初始化
-
-### 添加组件
-
-1. 在左侧组件库中找到需要的组件
-2. 将组件拖拽到设计区域
-3. 通过右侧属性面板配置组件参数
-
-### 连接组件
-
-1. 点击一个组件的输出引脚
-2. 拖动连线到目标组件的输入引脚
-3. 松开鼠标完成连接
-4. 连线会自动显示信号名称和类型
-
-### 验证设计
-
-1. 点击工具栏中的"验证"按钮
-2. 系统会自动检查设计中的错误和警告
-3. 如有问题,可查看错误日志进行修复
-
-### 模拟仿真
-
-1. 点击"仿真"按钮进入仿真模式
-2. 设置输入信号和仿真参数
-3. 运行仿真并查看波形输出
-4. 可通过时间轴查看不同时刻的信号状态
-
-### 烧录到设备
-
-1. 确保FPGA设备已连接
-2. 点击"合成"按钮生成比特流文件
-3. 点击"烧录"将设计下载到物理设备
-4. 查看烧录日志确认操作成功
-
-## 组件说明
-
-### 基础逻辑组件
-
-- **AND/OR/XOR门**:基本逻辑门,可设置输入数量
-- **MUX多路复用器**:数据选择器,根据选择信号输出不同输入
-- **触发器/寄存器**:存储单元,可选D、T、JK等不同类型
-- **计数器**:可配置位宽、计数方向等参数
-
-### 接口组件
-
-- **按钮/开关**:用户输入控制元件
-- **LED指示灯**:显示数字输出状态
-- **七段数码管**:显示数字信息
-- **UART接口**:串行通信接口
-
-### 高级组件
-
-- **RAM/ROM**:存储模块,可配置数据位宽和深度
-- **PLL/DCM**:时钟控制模块
-- **DSP模块**:数字信号处理单元
-- **MCU集成**:可嵌入微控制器核心
-
-## 常见问题
-
-### 设计无法编译
-
-检查以下可能的原因:
-- 组件之间连线不完整
-- 组件参数设置不正确
-- 存在时序冲突
-- 资源使用超出目标设备限制
-
-### 模拟结果与预期不符
-
-可能的解决方法:
-- 检查输入激励是否正确
-- 验证时钟设置和复位信号
-- 调整仿真时间步长
-- 查看信号完整传播路径
-
-### 设备烧录失败
-
-常见原因及解决方法:
-- 检查USB连接和驱动安装
-- 确认选择了正确的设备型号
-- 验证生成的比特流文件是否有效
-- 重新安装FPGA开发工具
-
-## 高级技巧
-
-### 层次化设计
-
-对于复杂项目,建议按功能模块划分设计层次,创建子模块后再进行顶层连接。
-
-### 自定义组件
-
-可以将常用电路打包为自定义组件,方便在不同项目中重复使用。
-
-### 版本控制
-
-定期保存设计快照,利用版本历史功能跟踪设计变更。
-
-### 性能优化
-
-- 减少关键路径上的组件数量
-- 优化时钟树结构
-- 合理布局减小互连延迟
-- 使用流水线结构提高吞吐量
-
-## 联系我们
-
-如有任何问题或建议,请通过以下方式联系我们:
-- 邮箱:support@fpgaweblab.com
-- 论坛:forum.fpgaweblab.com
-- 微信公众号:FPGA_WebLab
-
-感谢您使用FPGA WebLab!
-`;
-
- // 更新文档内容
- documentContent.value = mockDocContent;
-}
-
// --- 元器件管理 ---
const showComponentsMenu = ref(false);
const diagramData = ref({