verilog练习:i2c slave 模块设计

文章目录

  • 前言
  • 1.结构
  • 2.代码
    • 2.1 iic_slave.v
    • 2.2 sync.v
    • 2.3 wr_fsm.v
      • 2.3.1 状态机状态解释
    • 2.4 ram.v
  • 3. 波形展示
  • 4. 建议
  • 5. 资料总结


前言

首先就不啰嗦iic协议了,网上有不少资料都是叙述此协议的。

下面将是我本次设计的一些局部设计汇总,如果对读者有借鉴意义那最好,如果没有的话也无所谓,互相交流而已。(这是我早期的版本,注释比较少,代码编写比较混乱,读者自便)

希望读者发现问题可在下方留言,我会及时回答或者修改。


1.结构

顶层结构图在这里插入图片描述
master结构图
在这里插入图片描述
slave结构图
在这里插入图片描述

2.代码

2.1 iic_slave.v

`timescale 1ns/1ps

module iic_slave (
    input rstn,
    input clk,
    input scl,
    inout sda,
    input [7:0] q,  // RAM data to slave
    output wen,
    output [7:0] d, // Slave data to RAM
    output [7:0] a  // Slave address to RAM
);

// Internal signals
wire sync_scl_1;
wire sync_sda_1;
wire sda_posedge;
wire sda_negedge;
wire scl_posedge;
wire scl_negedge;
wire sda_out;
wire sda_oen;

// Three-state gate for SDA
assign sda = (sda_oen) ? sda_out : 1'bz;

// Instantiate sync module
sync sync (
    .clk(clk),
    .rstn(rstn),
    .scl(scl),
    .sda(sda),
    .sync_scl_1(sync_scl_1),
    .sync_sda_1(sync_sda_1),
    .sda_posedge(sda_posedge),
    .sda_negedge(sda_negedge),
    .scl_posedge(scl_posedge),
    .scl_negedge(scl_negedge)
);

// Instantiate RAM module
ram ram (
    .clk(clk),
    .rstn(rstn),
    .d(d),
    .a(a),
    .q(q),
    .wen(wen)
);

// Instantiate write FSM module
wr_fsm wr_fsm (
    .clk(clk),
    .rstn(rstn),
    .sync_scl_1(sync_scl_1),
    .sync_sda_1(sync_sda_1),
    .scl_posedge(scl_posedge),
    .scl_negedge(scl_negedge),
    .sda_posedge(sda_posedge),
    .sda_negedge(sda_negedge),
    .d(d),
    .a(a),
    .q(q),
    .wen(wen),
    .sda_out(sda_out),
    .sda_oen(sda_oen)
);

endmodule

2.2 sync.v

`timescale 1ns/1ps
module sync (
    rstn,
    clk,
    scl,
    sda,
    sync_scl_1,
    sync_sda_1,
    sda_posedge,
    sda_negedge,
    scl_posedge,
    scl_negedge
);

    input rstn;
    input clk;
    input scl;
    input sda;

    output sync_scl_1;
    output sync_sda_1;
    output sda_posedge;
    output sda_negedge;
    output scl_posedge;
    output scl_negedge;

    reg sync_scl_1;
    reg sync_sda_1;
    reg sync_scl_0;
    reg sync_sda_0;

    always @(posedge clk or negedge rstn) begin
        if (!rstn) begin
            sync_scl_1 <= 1'b0;
            sync_sda_1 <= 1'b0;
            sync_scl_0 <= 1'b0;
            sync_sda_0 <= 1'b0;
        end else begin
            sync_scl_0 <= scl;
            sync_sda_0 <= sda;
            sync_scl_1 <= sync_scl_0;
            sync_sda_1 <= sync_sda_0;
        end
    end

    assign sda_posedge = (sync_sda_0) & (~sync_sda_1);
    assign sda_negedge = (~sync_sda_0) & (sync_sda_1);
    assign scl_posedge = (sync_scl_0) & (~sync_scl_1);
    assign scl_negedge = (~sync_scl_0) & (sync_scl_1);

endmodule

2.3 wr_fsm.v

`timescale 1ns/1ps
module wr_fsm (
    rstn,
    clk,
    sync_scl_1,
    sync_sda_1,
    scl_posedge,
    scl_negedge,
    sda_posedge,
    sda_negedge,
    q,
    d,
    a,
    wen,
    sda_out,
    sda_oen
);

    input rstn, clk;
    input sync_scl_1;
    input sync_sda_1;
    input scl_posedge;
    input scl_negedge;
    input sda_posedge;
    input sda_negedge;
    input [7:0] q;
    output [7:0] d;
    output [7:0] a;
    output wen;
    output sda_out;
    output sda_oen;

    reg wen; // write and read flags reg
    reg [7:0] scl_cnt; // clk delay counter
    reg [3:0] bit_cnt; // valid transfer byte
    reg [7:0] a; // a = save word addr, shift data to ram
    reg sda_out; // data out reg
    reg sda_oen; // three state gate flag bit
    reg [7:0] save_ctrl; // store ctrl word
    reg [7:0] save_q_data; // store data of q
    wire [7:0] q;

    parameter slave_addr = 7'b1101101; // parameter slave addr
    parameter scl_cnt_max = 60-1;

    reg [3:0] state; // state transform
    parameter idle       = 4'd0,
              w_start   = 4'd1,
              w_ctrl    = 4'd2,
              ack1      = 4'd3,
              w_addr    = 4'd4,
              ack2      = 4'd5,
              w_data    = 4'd6,
              ack3      = 4'd7,
              r_start   = 4'd8,
              r_ctrl    = 4'd9,
              ack4      = 4'd10,
              r_data    = 4'd11,
              ack5      = 4'd12,
              stop      = 4'd13;

    always @(posedge clk or negedge rstn)
    begin
        if (!rstn) begin
            state <= idle;
            sda_oen <= 1'b0;
            sda_out <= 1'b1;
            scl_cnt <= 8'b0;
            bit_cnt <= 4'b0;
            sda_out <= 1'b0;
        end else begin
            case (state)
                idle: begin
                    // Initialize state and signals
                    state <= w_start;
                    sda_oen <= 1'b0;
                    sda_out <= 1'b1;
                    scl_cnt <= 8'b0;
                    bit_cnt <= 4'b0;
                    sda_out <= 1'b0;
                end

                w_start: begin
                    // Wait for start condition
                    if (sync_scl_1 && sda_negedge)
                        begin
                            state <= w_ctrl;
                            bit_cnt <= 4'd8;
                        end
                    else
                        state <= w_start;
                end

                w_ctrl: begin
                    // Control word transfer
                    if (scl_negedge)
                        begin
                            save_ctrl <= {save_ctrl[6:0], sync_sda_1};
                            bit_cnt <= bit_cnt - 1;
                            if (bit_cnt == 4'd0)
                                begin
                                    state <= ack1;
                                    bit_cnt <= 4'd8;
                                end
                            else
                                state <= w_ctrl;
                        end
                    else
                        state <= w_ctrl;
                end

                ack1: begin
                    // Acknowledge control word
                    if (save_ctrl[7:1] == slave_addr)
                        begin
                            scl_cnt <= scl_cnt + 8'b1;
                            if (scl_cnt == scl_cnt_max >> 2)
                                begin
                                    sda_out <= 0;
                                    sda_oen <= 1;
                                    state <= ack1;
                                end
                            else if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)
                                begin
                                    state <= w_addr;
                                    sda_oen <= 0;
                                    scl_cnt <= 8'b0;
                                    bit_cnt <= 4'd7;
                                end
                            else
                                state <= ack1;
                        end
                    else
                        state <= stop;
                end

                w_addr: begin
                    // Write address
                    if (scl_negedge)
                        begin
                            bit_cnt <= bit_cnt - 4'b1;
                            wen <= save_ctrl[0]; // write operation
                            a <= {a[6:0], sync_sda_1};
                            if (bit_cnt == 4'd0)
                                begin
                                    bit_cnt <= 4'd7;
                                    state <= ack2;
                                end
                            else
                                state <= w_addr;
                        end
                    else
                        state <= w_addr;
                end

                ack2: begin
                    // Acknowledge address
                    scl_cnt <= scl_cnt + 8'b1;
                    if (scl_cnt == scl_cnt_max >> 2)
                        begin
                            sda_out <= 1'b0;
                            sda_oen <= 1'b1;
                            state <= ack2;
                        end
                    else if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)
                        begin
                            sda_oen <= 1'b0;
                            scl_cnt <= 8'b0;
                            if (wen == 0) // decide write or read
                                state <= w_data;
                            else
                                state <= r_start;
                        end
                    else
                        state <= ack2;
                end

                w_data: begin
                    // Write data
                    if (scl_negedge)
                        begin
                            d <= {d[6:0], sync_sda_1};
                            bit_cnt <= bit_cnt - 4'b1;
                            if (bit_cnt == 4'd0)
                                begin
                                    bit_cnt <= 4'd7;
                                    state <= ack3;
                                end
                            else
                                state <= w_data;
                        end
                    else
                        state <= w_data;
                end

                ack3: begin
                    // Acknowledge data
                    scl_cnt <= scl_cnt + 8'b1;
                    if (scl_cnt == scl_cnt_max >> 2)
                        begin
                            sda_out <= 0;
                            sda_oen <= 1'b1;
                            state <= ack3;
                        end
                    else if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)
                        begin
                            sda_oen <= 1'b0;
                            scl_cnt <= 8'b0;
                            state <= stop;
                        end
                    else
                        state <= ack3;
                end

                r_start: begin
                    // Read start condition
                    if (sync_scl_1 && sda_negedge)
                        begin
                            sda_oen <= 1'b0;
                            bit_cnt <= 4'd8;
                            state <= r_ctrl;
                        end
                    else
                        state <= r_start;
                end

                r_ctrl: begin
                    // Read control word
                    if (scl_negedge)
                        begin
                            bit_cnt <= bit_cnt - 4'b1;
                            save_ctrl <= {save_ctrl[6:0], sync_sda_1};
                            if (bit_cnt == 4'd0)
                                begin
                                    wen <= save_ctrl[0];
                                    bit_cnt <= 4'd7;
                                    state <= ack4;
                                end
                            else
                                state <= r_ctrl;
                        end
                    else
                        state <= r_ctrl;
                end

                ack4: begin
                    // Acknowledge control word
                    if (save_ctrl[7:1] == slave_addr)
                        begin
                            scl_cnt <= scl_cnt + 8'b1;
                            if (scl_cnt == scl_cnt_max >> 2)
                                begin
                                    sda_out <= 0;
                                    sda_oen <= 1;
                                    state <= ack4;
                                end
                            else if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)
                                begin
                                    sda_oen <= 1'b0;
                                    scl_cnt <= 8'b0;
                                    if (wen)
                                        begin
                                            state <= r_data;
                                            sda_oen <= 1'b1;
                                            sda_out <= sync_sda_1;
                                        end
                                    else
                                        state <= w_data;
                                end
                            else
                                state <= ack4;
                        end
                    else
                        state <= stop;
                end

                r_data: begin
                    // Read data
                    if (scl_negedge)
                        begin
                            save_q_data <= q[7:0];
                            bit_cnt <= bit_cnt - 4'b1;
                            sda_out <= save_q_data[7];
                            if (bit_cnt == 4'd0)
                                begin
                                    state <= ack5;
                                    bit_cnt <= 4'd7;
                                    sda_oen <= 0;
                                end
                            else
                                begin
                                    state <= r_data;
                                    sda_oen <= 1;
                                    save_q_data <= {save_q_data[6:0], 1'b0};
                                end
                        end
                    else
                        state <= r_data;
                end

                ack5: begin
                    // Acknowledge data
                    if (scl_posedge)
                        begin
                            if (sync_sda_1 == 1)
                                state <= stop;
                            else
                                state <= idle;
                        end
                    else
                        state <= ack5;
                end

                stop: begin
                    // Stop condition
                    if (sync_scl_1 && sda_posedge)
                        begin
                            state <= idle;
                            sda_oen <= 1'b0;
                            sda_out <= 1'b1;
                        end
                    else
                        state <= stop;
                end

                default: state <= idle;
            endcase
        end
    end
endmodule


2.3.1 状态机状态解释

以下是代码中每个状态的作用解释:

reg [3:0] state; // state transform
parameter idle       = 4'd0,
          w_start   = 4'd1,
          w_ctrl    = 4'd2,
          ack1      = 4'd3,
          w_addr    = 4'd4,
          ack2      = 4'd5,
          w_data    = 4'd6,
          ack3      = 4'd7,
          r_start   = 4'd8,
          r_ctrl    = 4'd9,
          ack4      = 4'd10,
          r_data    = 4'd11,
          ack5      = 4'd12,
          stop      = 4'd13;

状态作用解释

  1. idle (4’d0):
  • 作用: 初始状态,等待复位信号或起始条件。
  • 描述: 在这个状态下,所有信号被初始化,状态机等待复位信号 rstn 或起始条件(sync_scl_1 和 sda_negedge)。
  1. w_start (4’d1):
  • 作用: 等待起始条件。
  • 描述: 在这个状态下,状态机检测起始条件(sync_scl_1 和 sda_negedge)。如果检测到起始条件,状态机进入 w_ctrl 状态。
  1. w_ctrl (4’d2):
  • 作用: 接收控制字。
  • 描述: 在这个状态下,状态机接收控制字(save_ctrl),并将其存储在寄存器中。控制字的接收通过 scl_negedge 信号完成。当接收到完整的控制字后,状态机进入 ack1 状态。
  1. ack1 (4’d3):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。如果接收到的控制字匹配从设备地址(slave_addr),状态机进入 w_addr 状态。否则,状态机进入 stop 状态。
  1. w_addr (4’d4):
  • 作用: 接收地址。
  • 描述: 在这个状态下,状态机接收地址数据(a),并将其存储在寄存器中。地址的接收通过 scl_negedge 信号完成。当接收到完整的地址后,状态机进入 ack2 状态。
  1. ack2 (4’d5):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。根据控制字中的写入标志(wen),状态机决定进入 w_data 状态(写入数据)或 r_start 状态(读取数据)。
  1. w_data (4’d6):
  • 作用: 写入数据。
  • 描述: 在这个状态下,状态机接收数据(d),并将其存储在寄存器中。数据的接收通过 scl_negedge 信号完成。当接收到完整的数据后,状态机进入 ack3 状态。
  1. ack3 (4’d7):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。然后状态机进入 stop 状态。
  1. r_start (4’d8):
  • 作用: 等待读取起始条件。
  • 描述: 在这个状态下,状态机检测读取起始条件(sync_scl_1 和 sda_negedge)。如果检测到起始条件,状态机进入 r_ctrl 状态。
  1. r_ctrl (4’d9):
  • 作用: 接收控制字。
  • 描述: 在这个状态下,状态机接收控制字(save_ctrl),并将其存储在寄存器中。控制字的接收通过 scl_negedge 信号完成。当接收到完整的控制字后,状态机进入 ack4 状态。
  1. ack4 (4’d10):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。如果接收到的控制字匹配从设备地址(slave_addr),状态机进入 r_data 状态。否则,状态机进入 stop 状态。
  1. r_data (4’d11):
  • 作用: 读取数据。
  • 描述: 在这个状态下,状态机读取数据(q),并将其存储在寄存器中。数据的读取通过 scl_negedge 信号完成。当读取完数据后,状态机进入 ack5 状态。
    13。 ack5 (4’d12):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。然后状态机进入 idle 状态。
  1. stop (4’d13):
  • 作用: 停止状态。
  • 描述: 在这个状态下,状态机等待停止条件(sync_scl_1 和 sda_posedge)。如果检测到停止条件,状态机进入 idle 状态。

每个状态的作用如下:

  • idle: 初始状态,等待复位或起始条件。
  • w_start: 等待起始条件。
  • w_ctrl: 接收控制字。
  • ack1: 发送 ACK 信号,确认控制字接收。
  • w_addr: 接收地址。
  • ack2: 发送 ACK 信号,确认地址接收。
  • w_data: 写入数据。
  • ack3: 发送 ACK 信号,确认数据写入。
  • r_start: 等待读取起始条件。
  • r_ctrl: 接收控制字。
  • ack4: 发送 ACK 信号,确认控制字接收。
  • r_data: 读取数据。
  • ack5: 发送 ACK 信号,确认数据读取。
  • stop: 停止状态,等待停止条件。

这些状态共同构成了一个完整的 I2C 从设备写入和读取的有限状态机,确保数据的正确传输和接收。

2.4 ram.v

`timescale 1ns/1ps
module ram (
    clk,
    rstn,
    d,
    a,
    q,
    wen
);

    // Input ports
    input clk, rstn;
    input [7:0] a;  // Address input
    input [7:0] d;  // Data input
    input wen;      // Write enable

    // Output ports
    output [7:0] q; // Data output

    // Internal registers
    reg [7:0] ram [255:0]; // RAM array
    integer i;             // Loop counter
    reg [7:0] q;           // Output data register

    // Always block for RAM operations
    always @(posedge clk or negedge rstn)
    begin
        if (!rstn) begin
            // Initialize RAM on reset
            for (i = 0; i <= 255; i = i + 1)
                ram[i] <= 8'b0;
        end else begin
            if (!wen) begin
                // Write operation: wen = 0
                ram[a] <= d;
            end else begin
                // Read operation: wen = 1
                q <= ram[a];
            end
        end
    end

endmodule


3. 波形展示

在这里插入图片描述

4. 建议

必看
此设计还存在一些问题,后续有时间我会完善的。

在同步的时候我建议还是使用两个寄存器缓冲,而不是使用一个,使用多个更加的稳妥一些,我这个就是使用了较少的寄存器缓冲,所以波形中有问题。(我把这段字打个红色背景)。(是因为在边沿检测的时候无法确认信号是否同步还是异步所以在设计的时候还是使用双寄存器进行消除亚稳态)

5. 资料总结

练习时的一些思路。

https://blog.csdn.net/weixin_46163885/article/details/107170689

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/969056.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【竞技宝】PGL瓦拉几亚S4预选:Tidebound2-0轻取spiky

北京时间2月13日,DOTA2的PGL瓦拉几亚S4预选赛继续进行,昨日进行的中国区预选赛胜者组首轮Tidebound对阵的spiky比赛中,以下是本场比赛的详细战报。 第一局: 首局比赛,spiky在天辉方,Tidebound在夜魇方。阵容方面,spiky点出了幻刺、火枪、猛犸、小强、巫妖,Tidebound则是拿到飞…

Android RenderEffect对Bitmap高斯模糊(毛玻璃),Kotlin(1)

Android RenderEffect对Bitmap高斯模糊(毛玻璃)&#xff0c;Kotlin&#xff08;1&#xff09; import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.HardwareRenderer import android.graphics.PixelFormat import android.graphic…

AI前端开发的崛起与ScriptEcho的助力

近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术飞速发展&#xff0c;深刻地改变着软件开发的格局。尤其是在前端开发领域&#xff0c;AI的应用越来越广泛&#xff0c;催生了对AI写代码工具的需求激增&#xff0c;也显著提升了相关人才的市场价值。然而&#xff0c;…

【Mac排错】ls: command not found 终端命令失效的解决办法

【TroubleShooting on Mac】ls: command not found 终端命令失效的解决办法 A Solution to Solve “Command not found” of Terminal on Mac 一直在使用心爱的MacBook Pro的Terminal&#xff0c;并且为她定制了不同的Profile。 这样&#xff0c;看起来她可以在不同季节&…

DexVLA:通用机器人控制中具有插件式扩散专家的视觉语言模型

25年2月来自美的集团和华东师范的论文“DexVLA: Vision-Language Model with Plug-In Diffusion Expert for General Robot Control”。 让机器人能够在不同的环境中执行不同的任务是机器人学习的核心挑战。虽然视觉-语言-动作 (VLA) 模型已显示出可泛化机器人技能的前景&…

【微服务学习一】springboot微服务项目构建以及nacos服务注册

参考链接 3. SpringCloud - 快速通关 springboot微服务项目构建 教程中使用的springboot版本是3.x&#xff0c;因此需要使用jdk17&#xff0c;并且idea也需要高版本&#xff0c;我这里使用的是IDEA2024。 环境准备好后我们就可以创建springboot项目&#xff0c;最外层的项目…

DeepSeek 助力 Vue 开发:打造丝滑的返回顶部按钮(Back to Top)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

deepseek大模型,本地搭建deepseek模型,springai调用本地deepseek模型,java调用deepseek大模型api

文档对应的视频地址&#xff1a; https://www.bilibili.com/video/BV1V8NBevEjk/?spm_id_from333.1387.homepage.video_card.click&vd_source14d27ec13a4737c281b7c79463687112SpringAI调用本地deepseek模型 一、 使用deepseek步骤 官网注册账号 地址&#xff1a; https…

大模型语言简介

大模型语言能做什么 信息提取 将长段文字中的信息抽取出来并且以结构化的方式输出。相比起传统NLP的方式&#xff0c;大模型在泛化能力上有非常大的提升&#xff0c;并且开发成本要低2个数量级。应用场景包括&#xff1a;论文论点论据提取、用户画像提取、舆情分析、病例结构…

计算机毕业设计Python旅游评论情感分析 NLP情感分析 LDA主题分析 bayes分类 旅游爬虫 旅游景点评论爬虫 机器学习 深度学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

FreeRtos实时系统: 十二.FreeRTOS的队列集

FreeRtos实时系统: 十二.FreeRTOS的队列集 一.队列集简介二.队列集相关API函数三.队列集操作实验 一.队列集简介 左边的接收任务会在没接收到队列时会阻塞&#xff0c;如果前面释放信号量这时该任务也获取不到信号量。 右边使用队列集如果获取到&#xff0c;判断句柄是谁&#…

vsftpd 编译安装流程

目录 vsftpd 编译安装流程1、下载源码包并上传致服务器解压2、进入源码目录后编译源码文件3、将对应文件安装到指定位置4、准备 vsftpd 的运行环境5、启动 vsftpd 服务进行测试6、编译安装说明 vsftpd 编译安装流程 1、下载源码包并上传致服务器解压 源码包下载地址&#xff1…

【Android开发】华为手机安装包安装失败“应用是非正式版发布版本,当前设备不支持安装”问题解决

问题描述 我们将Debug版本的安装包发送到手机上安装&#xff0c;会发现华为手机有如下情况 解决办法 在文件gradle.properties中粘贴代码&#xff1a; android.injected.testOnlyfalse 最后点击“Sync now”&#xff0c;等待重新加载gradle资源即可 后面我们重新编译Debug安装…

计算机网络-八股-学习摘要

一&#xff1a;HTTP的基本概念 全称&#xff1a; 超文本传输协议 从三个方面介绍HTTP协议 1&#xff0c;超文本&#xff1a;我们先来理解「文本」&#xff0c;在互联网早期的时候只是简单的字符文字&#xff0c;但现在「文本」的涵义已经可以扩展为图片、视频、压缩包等&am…

八大排序——归并排序

目录 1.基本思想 2.动态图 3.分解的时候我们可以使用递归的方式进行 代码解释 1. main 方法 2. mergeSort 方法 3. merge 方法 示例运行过程 初始数组 每轮排序后的数组 代码总结 合并两个有序序列 1.基本思想 归并排序就是递归得将原始数组递归对半分隔&#xff0c…

C++ Primer 跳转语句

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

Elasticsearch:15 年来致力于索引一切,找到重要内容

作者&#xff1a;来自 Elastic Shay Banon 及 Philipp Krenn Elasticsearch 刚刚 15 岁了&#xff01;回顾过去 15 年的索引和搜索&#xff0c;并展望未来 15 年的相关内容。 Elasticsearch 刚刚成立 15 周年。一切始于 2010 年 2 月的一篇公告博客文章&#xff08;带有标志性的…

后稀缺社会的经济模型:当技术突破资源边界时的范式革命

文章目录 引言:走出马尔萨斯陷阱一、技术基础:构建后稀缺社会的四大支柱1.1 自动化生产系统:边际成本趋零的物理基础1.2 能源基础设施:聚变-光伏-储能的黄金三角二、经济模型转变:从稀缺范式到丰裕范式2.1 传统经济模型的失效2.2 新价值方程的涌现三、后稀缺经济的三层架构…

macOS部署DeepSeek-r1

好奇&#xff0c;跟着网友们的操作试了一下 网上方案很多&#xff0c;主要参考的是这篇 DeepSeek 接入 PyCharm&#xff0c;轻松助力编程_pycharm deepseek-CSDN博客 方案是&#xff1a;PyCharm CodeGPT插件 DeepSeek-r1:1.5b 假设已经安装好了PyCharm PyCharm: the Pyth…

记录-rtsp 链接中账号密码包含有@的导致解析失败

问题&#xff1a; 在使用librtsp开源库的时候发现&#xff0c;当输入的rtsp流包含有多个的时候 (比如账号密码中包含,rtsp://admin:Pssw0rd192.168.31.xxx/Streaming/Channels/101)&#xff0c;会导致拉流失败。 问题处理&#xff1a; 一、这是因为librtsp中只对一个做了解析…