当前位置: 首页 > news >正文

Verilog基础(三):过程

过程(Procedures)

- Always块 – 组合逻辑 (Always blocks – Combinational)

由于数字电路是由电线相连的逻辑门组成的,所以任何电路都可以表示为模块和赋值语句的某种组合.

然而,有时这不是描述电路最方便的方法.

两种always block是十分有用的:

  • 组合逻辑: always @(*)
  • 时序逻辑: always @(posedge clk)

always @(*)就相当于赋值语句–assign,因此选择哪一种语法仅仅取决与方便程度.

block内还有更丰富的语句集,比如if-else,case等等.但不能包含连续赋值即不可包含assign,因为他与always @(*)冲突.

以下语句是等价的

assign out1 = a & b | c ^ d;
always @(*) out2 = a & b | c ^ d;

  • Module Declaraction
module top_module(input a, input b,output wire out_assign,output reg out_alwaysblock
);
  • Solution
// synthesis verilog_input_version verilog_2001
module top_module(input a, input b,output wire out_assign,output reg out_alwaysblock
);assign out_assign = a&b;always @(*) out_alwaysblock = a&b;
endmodule
- Always块 – 时序逻辑 (Always blocks – Clocked)

verilog中有三种赋值方式:

  • 连续赋值: assign x = y; 不能在always-block内使用
  • 阻塞赋值: x = y;, 只能在always-block内使用
  • 非阻塞赋值: x <= y,只能在always-block内使用

请在组合逻辑中使用阻塞赋值,在时序逻辑中使用非阻塞赋值
否则将产生难以发现的错误

请实现如下电路:

  • Module Declaraction
module top_module(input clk,input a,input b,output wire out_assign,output reg out_always_comb,output reg out_always_ff   );
  • Solution
// synthesis verilog_input_version verilog_2001
module top_module(input clk,input a,input b,output wire out_assign,output reg out_always_comb,output reg out_always_ff   );
assign out_assign = a^b;always @(*) out_always_comb = a^b;always @(posedge clk) out_always_ff <= a^b;
endmodule
- If语句

if语句通常创建一个2对1的多路选择器,如果条件为真,则选择一个输入,如果条件为假,则选择另一个输入.

以下两种写法是等价的:

always @(*) beginif (condition) beginout = x;endelse beginout = y;end
endassign out = (condition) ? x : y;

建立一个在a和b之间选择的2对1多路选择器.如果sel_b1和sel_b2都为真,则选择b.否则,选择a.

执行相同的操作两次,一次使用assign语句,一次使用if语句.

  • Module Declaraction
module top_module(input a,input b,input sel_b1,input sel_b2,output wire out_assign,output reg out_always   ); 
  • Solution
// synthesis verilog_input_version verilog_2001
module top_module(input a,input b,input sel_b1,input sel_b2,output wire out_assign,output reg out_always   ); assign out_assign = (sel_b1&sel_b2)?b:a;always @(*) beginif(sel_b1&sel_b2) beginout_always = b;endelse beginout_always = a;endend
endmodule
- If语句引发的锁存(latches)

以下代码包含锁存的错误行为.

  • Module Declaraction
always @(*) beginif (cpu_overheated)shut_off_computer = 1;
endalways @(*) beginif (~arrived)keep_driving = ~gas_tank_empty;
end
  • Solution
// synthesis verilog_input_version verilog_2001
module top_module (input      cpu_overheated,output reg shut_off_computer,input      arrived,input      gas_tank_empty,output reg keep_driving  ); //always @(*) beginif (cpu_overheated) beginshut_off_computer = 1;endelse beginshut_off_computer = 0;endendalways @(*) beginif (~arrived&~gas_tank_empty) beginkeep_driving = ~gas_tank_empty&(~arrived);endelse beginkeep_driving = ~(gas_tank_empty|arrived);endendendmodule

If语句在硬件描述语言(如Verilog)中用于描述受条件控制的电路。然而,不当的If语句使用可能会引发锁存器(latches)的产生,这在FPGA或ASIC设计中通常是不希望看到的。以下是对If语句引发锁存器的详细分析:

  • 一、锁存器的基本概念

锁存器是一种在异步电路系统中对输入信号电平敏感的单元,用来存储信息。当锁存信号有效时,数据被锁存,输入信号不再起作用。锁存器也被称为透明锁存器,因为不锁存时输出对于输入是透明的。

  • 二、If语句引发锁存器的情况

    在Verilog中,If语句引发锁存器的情况主要包括以下几种:

    1. 组合逻辑中If语句缺少Else分支

      • 在组合逻辑电路中,如果If语句没有覆盖所有可能的条件,并且没有提供Else分支来指定其他条件下的输出,那么综合工具可能会推断出一个锁存器行为来保持上一个状态。
      • 例如,if (enable) reg <= data;enable为假时,reg的值将保持不变,这可能导致锁存器的产生。
    2. 敏感信号列表不完整

      • always块中使用非阻塞赋值(<=)时,如果没有显式的敏感信号列表或者敏感信号列表不完整,也可能导致锁存器的产生。
      • 这是因为综合器可能无法正确判断何时应更新信号,从而推断出锁存器行为来保持信号状态。
    3. 输出变量赋值给自己

      • 在If语句或组合逻辑中,如果输出变量被赋值给自己(即赋值表达式中包含输出变量自身),也可能导致锁存器的产生。
      • 这是因为输出变量需要具有存储功能来保持其上一个状态。
  • 三、避免If语句引发锁存器的策略

    为了避免If语句引发锁存器,可以采取以下策略:

    1. 确保If语句结构完整

      • 在组合逻辑中,确保If语句覆盖所有可能的条件,并提供Else分支来指定其他条件下的输出。
      • 这有助于确保输出在所有条件下都有一个已知的状态,从而避免锁存器的产生。
    2. 使用阻塞赋值明确表达组合逻辑

      • 在组合逻辑中,使用阻塞赋值(=)来明确表达逻辑关系,而不是使用非阻塞赋值。
      • 这有助于综合工具正确识别组合逻辑并避免推断出锁存器。
    3. 完善敏感信号列表

      • 在使用非阻塞赋值时,确保always块有完整的敏感信号列表。
      • 这有助于综合工具正确判断何时应更新信号并避免锁存器的产生。
    4. 避免输出变量赋值给自己

      • 在组合逻辑中,避免将输出变量赋值给自己。
      • 如果需要保持上一个状态,可以考虑使用触发器(Flip-Flop)而不是锁存器。
  • 四、锁存器的危害与替代方案

锁存器在FPGA或ASIC设计中可能带来以下危害:

  1. 不可预测的时序行为:锁存器的输出取决于输入信号的持续电平,而不是特定的时钟边沿,这使得时序分析和预测更加困难。
  2. 系统不稳定:由于锁存器的输出直接由输入决定,任何输入上的噪声或毛刺都会立即反映到输出上,可能导致系统不稳定或误操作。
  3. 资源利用率降低:FPGA内部的锁存器实现通常不如寄存器高效,可能降低资源利用率并增加功耗。

因此,在FPGA设计中,通常推荐使用寄存器(触发器)来代替锁存器,除非有特殊的应用场景要求锁存器的使用。寄存器在时钟边沿更新,提供了更可预测和稳定的行为,便于时序分析和设计验证。

综上所述,If语句在硬件描述语言中的使用需要谨慎,以避免引发不必要的锁存器。通过确保If语句结构完整、使用阻塞赋值明确表达组合逻辑、完善敏感信号列表以及避免输出变量赋值给自己等策略,可以有效避免锁存器的产生。


- Case语句

verilog中的case语句几乎等同于if elseif else的序列,该序列将一个表达式与其他表达式列表进行比较.它的语法和功能与C语言中的switch语句不同.

always @(*) begin     // This is a combinational circuitcase (in)1'b1: begin out = 1'b1;  // begin-end if >1 statementend1'b0: out = 1'b0;default: out = 1'bx;endcase
end
  • case语句以case开头,每个"case item"以冒号结尾,没有switch
  • 每个case项只能执行一条语句.这使得C中使用的“break”不必要.但这意味着如果需要多个语句,必须使用begin…end

如果有大量选项的情况,case语句比if语句更方便.因此,在本练习中,创建一个6对1的多路选择器.当sel介于0和5之间时,选择相应的数据输入,否则,输出0.数据输入和输出均为4位宽.小心锁存.

  • Module Declaraction
module top_module ( input [2:0] sel, input [3:0] data0,input [3:0] data1,input [3:0] data2,input [3:0] data3,input [3:0] data4,input [3:0] data5,output reg [3:0] out   );
  • Solution
// synthesis verilog_input_version verilog_2001
module top_module ( input [2:0] sel, input [3:0] data0,input [3:0] data1,input [3:0] data2,input [3:0] data3,input [3:0] data4,input [3:0] data5,output reg [3:0] out   );//always@(*) begin  // This is a combinational circuitcase(sel)3'b0: beginout = data0;end3'b001: beginout = data1;end3'b010: beginout = data2;end3'b011: beginout = data3;end3'b100: beginout = data4;end3'b101: beginout = data5;enddefault: beginout[3:0] = 0;endendcaseendendmodule
- 简单编码器1

priority encoder是一种组合电路,当输入一个vector时,输出第一个’1’出现的位置.例如:输入8’b10010000,输出3’d4,因为[4]是第一个高位.
构建一个4位encoder,若全是低位则输出0.

  • Module Declaraction
module top_module (input [3:0] in,output reg [1:0] pos  );
  • Solution
// synthesis verilog_input_version verilog_2001
module top_module (input [3:0] in,output reg [1:0] pos  );always @(*) beginif (in[0] == 1'b1) beginpos = 2'd0;endelse beginif(in[1] == 1'b1) beginpos = 2'd1;endelse beginif(in[2] == 1'b1) beginpos = 2'd2;endelse beginif(in[3] == 1'b1) beginpos = 2'd3;endelse beginpos = 0;endendendendend
endmodule
- 简单编码器2

假如现在输入是8位,那么就会有256种情况,我们可以使用casez来将item减少到9种.
例如:

always @(*) begincasez (in[3:0])4'bzzz1: out = 0;   // in[3:1] can be anything4'bzz1z: out = 1;4'bz1zz: out = 2;4'b1zzz: out = 3;default: out = 0;endcase
end
  • Module Declaraction
module top_module (input [7:0] in,output reg [2:0] pos  );
  • Solution
// synthesis verilog_input_version verilog_2001
module top_module (input [7:0] in,output reg [2:0] pos  );
always @(*) begincasez (in[7:0])8'bzzzzzzz1: beginpos = 3'd0;end8'bzzzzzz1z: beginpos = 3'd1;end8'bzzzzz1zz: beginpos = 3'd2;end8'bzzzz1zzz: beginpos = 3'd3;end8'bzzz1zzzz: beginpos = 3'd4;end8'bzz1zzzzz: beginpos = 3'd5;end8'bz1zzzzzz: beginpos = 3'd6;end8'b1zzzzzzz: beginpos = 3'd7;enddefault: beginpos = 0;endendcase
end
endmodule
- 避免锁存

假设您正在构建一个电路来处理游戏中PS/2键盘的扫描代码.

接收到的最后两个字节的扫描代码,您需要判断是否已按下键盘上的一个箭头键.这涉及到一个相当简单的映射,它可以使用一个case语句(或者如果elseif)实现,有四个case.

Scancode [15:0]Arrow key
16’he06bleft arrow
16’he072down arrow
16’he074right arrow
16’he075up arrow
Anythingelse none

为了避免创建锁存,必须在所有可能的条件下为所有输出分配一个值

  • Module Declaraction
module top_module (input [15:0] scancode,output reg left,output reg down,output reg right,output reg up  ); 
  • Solution
// synthesis verilog_input_version verilog_2001
module top_module (input [15:0] scancode,output reg left,output reg down,output reg right,output reg up  ); always @(*) beginleft = 0;down = 0;left = 0;right = 0;case (scancode)16'he06b: beginleft = 1;end16'he072: begindown = 1;end16'he074: beginright = 1;end16'he075: beginup = 1;enddefault: beginup = 0;down = 0;left = 0;right = 0;endendcaseend
endmodule

更多语法特点

verilog也有像C一样的三目算符:

- 三目算符

verilog也有像C一样的三目算符:

condition ? true : false;

给定四个无符号数,求其最小值.

  • Module Declaraction
module top_module (input [7:0] a, b, c, d,output [7:0] min);
  • Solution
module top_module (input [7:0] a, b, c, d,output [7:0] min);//// assign intermediate_result1 = compare? true: false;wire [7:0]min1,min2;assign min1=(a<b?a:b);assign min2 = (min1<c?min1:c);assign min = (min2<d?min2:d);
endmodule
- 优化运算1

奇偶校验经常被用来作为一种简单的方法检测错误.

创建一个电路,该电路将为一个8位字节计算一个奇偶校验位.

即计算输入8个位的异或

  • Module Declaraction
module top_module (input [7:0] in,output parity); 
  • Solution
module top_module (input [7:0] in,output parity); assign parity = ^in[7:0];
endmodule
- 优化运算2

建立如下电路:

  • out_and: 对输入数据求与

  • out_or: 对输入数据求或

  • out_xor:对输入数据求异或

  • Module Declaraction

module top_module( input [99:0] in,output out_and,output out_or,output out_xor 
);
  • Solution
module top_module( input [99:0] in,output out_and,output out_or,output out_xor 
);assign out_and = &in[99:0];assign out_or = |in[99:0];assign out_xor = ^in[99:0];
endmodule
- 循环 – 组合逻辑:实现Vector反转

反转vector顺序

  • Module Declaraction
module top_module( input [99:0] in,output [99:0] out
);
  • Solution
module top_module( input [99:0] in,output [99:0] out
);integer i;always @(*) beginfor(i=0;i<=99;i=i+1)out[7'd99-i] <= in[i];end
endmodule
- 循环 – 组合逻辑:实现255位计数器

计算vector中1的个数

  • Module Declaraction
module top_module( input [254:0] in,output [7:0] out );
  • Solution
module top_module( input [254:0] in,output [7:0] out );integer i;reg [7:0]count;always @(*) begincount=0;for(i=0;i<=254;i=i+1) beginif(in[i] == 1) begincount = count + 7'b1;endendendassign out = count;
endmodule
- 循环:实现100位加法器

通过实例化100个全加器构建一个100位加法器.

  • Module Declaraction
module top_module( input [99:0] a, b,input cin,output [99:0] cout,output [99:0] sum );
  • Solution
module top_module( input [99:0] a, b,input cin,output [99:0] cout,output [99:0] sum );reg [100:0]cin1;generategenvar i;for(i=0;i<100;i=i+1) begin:addsif(i==0) begin        add ins(a[i],b[i],cin,sum[i],cout[i]);            assign cin1[i+1]=cout[i];end            else beginadd ins(a[i],b[i],cin1[i],sum[i],cout[i]);assign cin1[i+1]=cout[i];            endendendgenerate
endmodulemodule add(input a, input b, input cin, output sum, output cout);assign {cout,sum}=a+b+cin;
endmodule
- 循环:实现100位BCD加法器

在Verilog中实现一个100位的BCD(Binary-Coded Decimal)加法器相对复杂,因为BCD编码的每个数字占用4位二进制数,所以100位的BCD数实际上表示的是25位的十进制数(100位 / 4位/十进制数字 = 25个十进制数字)。

BCD加法的一个关键问题是进位处理。在普通的二进制加法中,进位是逐位传递的,但在BCD加法中,每四位(一个BCD数字)之间可能需要额外的调整来处理从低位到高位的进位,以确保结果仍然是有效的BCD数。这通常涉及到将非BCD的中间结果转换为BCD格式。

以下是一个简化的Verilog代码示例,用于实现两个4位BCD数的加法,并调整结果以确保它是有效的BCD数。请注意,这个示例并没有直接扩展到100位,但它提供了一个基础,你可以在这个基础上构建更复杂的100位BCD加法器。

module bcd_adder_4bit(input [3:0] a, // 4-bit BCD inputinput [3:0] b, // 4-bit BCD inputinput cin,     // Carry-inoutput [3:0] sum, // 4-bit BCD outputoutput cout    // Carry-out
);wire [4:0] temp_sum; // 5-bit temporary sum to handle carrywire [3:0] adjusted_sum; // 4-bit adjusted BCD sumwire temp_cout; // Temporary carry-out// Perform binary addition of the BCD digits and the carry-inassign temp_sum = a + b + cin;assign temp_cout = (temp_sum[4] == 1'b1); // Carry-out if the sum is 5-bits wide// BCD adjustment: if the result is greater than or equal to 10 (0xA in BCD), adjust it// to be in the range 0-9 by subtracting 6 (0x6 in BCD) and setting the carry-out for the next BCD digitassign adjusted_sum = (temp_sum >= 4'd10) ? (temp_sum - 4'd6) : temp_sum[3:0];// Carry-out for the next BCD digit is set if the original sum was 10 or more, or if there was a carry-in and the sum was exactly 9wire carry_adjustment = (temp_sum == 4'd10) | (cin && temp_sum == 4'd9);assign cout = temp_cout | carry_adjustment;// Output the adjusted sumassign sum = adjusted_sum;endmodule

要构建一个100位的BCD加法器,你需要将上述4位BCD加法器模块级联25次(因为100位/4位/数字=25个数字)。每个模块的输出cout将作为下一个模块的cin。同时,你需要一个额外的机制来处理最高位可能产生的进位(如果两个加数的和超过最大的25位BCD数)。

请注意,这个示例代码没有考虑所有可能的边界情况和优化。在实际应用中,你可能需要更复杂的逻辑来处理溢出、零检测、符号扩展等问题。此外,对于大规模设计,使用高级综合工具或手动优化可能有助于提高性能和资源利用率。

相关文章:

Verilog基础(三):过程

过程(Procedures) - Always块 – 组合逻辑 (Always blocks – Combinational) 由于数字电路是由电线相连的逻辑门组成的&#xff0c;所以任何电路都可以表示为模块和赋值语句的某种组合. 然而&#xff0c;有时这不是描述电路最方便的方法. 两种always block是十分有用的&am…...

生成式AI安全最佳实践 - 抵御OWASP Top 10攻击 (上)

今天小李哥将开启全新的技术分享系列&#xff0c;为大家介绍生成式AI的安全解决方案设计方法和最佳实践。近年来&#xff0c;生成式 AI 安全市场正迅速发展。据 IDC 预测&#xff0c;到 2025 年全球 AI 安全解决方案市场规模将突破 200 亿美元&#xff0c;年复合增长率超过 30%…...

.Net WebAPI -[HttpPut(“{fileServiceId:int}“)]

[HttpPut("{fileServiceId:int}")] 这个写法是 ASP.NET Core 中的一个路由特性&#xff0c;用于定义一个 HTTP PUT 请求的路由&#xff0c;并指定路由参数的类型。 解析 HttpPut [HttpPut]&#xff1a; 这是一个 ASP.NET Core 的路由特性&#xff0c;用于标记一个方…...

[EAI-027] RDT-1B,目前最大的用于机器人双臂操作的机器人基础模型

Paper Card 论文标题&#xff1a;RDT-1B: a Diffusion Foundation Model for Bimanual Manipulation 论文作者&#xff1a;Songming Liu, Lingxuan Wu, Bangguo Li, Hengkai Tan, Huayu Chen, Zhengyi Wang, Ke Xu, Hang Su, Jun Zhu 论文链接&#xff1a;https://arxiv.org/ab…...

C基础寒假练习(7)

一、有 1、2、3、4个数字&#xff0c;能组成多少互不相同且无重复的三位&#xff1f; 都是多少&#xff1f; #include <stdio.h> int main() {// 定义数字数组int digits[] {1, 2, 3, 4};int n sizeof(digits) / sizeof(digits[0]);// 嵌套循环遍历所有排列for (int …...

Ajax:重塑Web交互体验的人性化探索

在数字化时代&#xff0c;网页的交互性和响应速度已成为衡量用户体验的关键指标。Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;&#xff0c;作为前端与后端沟通的桥梁&#xff0c;凭借其异步通信的能力&#xff0c;极大地提升了网页的动态性和用户友好度&…...

【DeepSeek背后的技术】系列二:大模型知识蒸馏(Knowledge Distillation)

目录 1 引言2 操作步骤和公式说明2.1 准备教师模型&#xff08;Teacher Model&#xff09;和学生模型&#xff08;Student Model&#xff09;2.2 生成软标签&#xff08;Soft Labels&#xff09;2.3 定义蒸馏损失函数2.4 训练学生模型2.5 调整超参数2.6 评估与部署 3 其他知识蒸…...

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.14 内存映射:处理超大型数组的终极方案

2.14 内存映射&#xff1a;处理超大型数组的终极方案 目录 #mermaid-svg-G91Kn9O4eN2k8xEo {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-G91Kn9O4eN2k8xEo .error-icon{fill:#552222;}#mermaid-svg-G91Kn9O4eN2k…...

【C++】STL——vector的使用

目录 &#x1f495;1.vector介绍 &#x1f495;2.vector的基本用法 &#x1f495;3.vector功能的具体用法 &#xff08;讲解&#xff09; &#x1f495;4.vector——size&#xff0c;capacity函数的使用 &#xff08;简单略讲&#xff09; &#x1f495;5.resize&#xff…...

springboot/ssm互联网智慧医院体检平台web健康体检管理系统Java代码编写

springboot/ssm互联网智慧医院体检平台web健康体检管理系统Java代码编写 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&am…...

介绍一下Mybatis的Executor执行器

Executor执行器是用来执行我们的具体的SQL操作的 有三种基本的Executor执行器&#xff1a; SimpleExecutor简单执行器 每执行一次update或select&#xff0c;就创建一个Statement对象&#xff0c;用完立刻关闭Statement对象 ReuseExecutor可重用执行器 可重复利用Statement…...

Wide Deep 模型:记忆能力与泛化能力

实验和完整代码 完整代码实现和jupyter运行&#xff1a;https://github.com/Myolive-Lin/RecSys--deep-learning-recommendation-system/tree/main 引言 Wide & Deep 模型是一种结合了线性模型&#xff08;Wide&#xff09;和深度神经网络&#xff08;Deep&#xff09;的混…...

Hot100之矩阵

73矩阵置零 题目 思路解析 收集0位置所在的行和列 然后该行全部初始化为0 该列全部初始化为0 代码 class Solution {public void setZeroes(int[][] matrix) {int m matrix.length;int n matrix[0].length;List<Integer> list1 new ArrayList<>();List<…...

Python语言的安全开发

Python语言的安全开发 引言 在信息技术迅速发展的今天&#xff0c;网络安全问题愈发凸显。随着Python语言的广泛应用&#xff0c;尤其是在数据分析、人工智能、Web开发等领域&#xff0c;其安全问题越来越受到重视。Python作为一门高效且易于学习的编程语言&#xff0c;虽然在…...

蓝桥杯刷题DAY3:Horner 法则 前缀和+差分数组 贪心

所谓刷题&#xff0c;最重要的就是细心 &#x1f4cc; 题目描述 在 X 进制 中&#xff0c;每一数位的进制不固定。例如&#xff1a; 最低位 采用 2 进制&#xff0c;第二位 采用 10 进制&#xff0c;第三位 采用 8 进制&#xff0c; 则 X 进制数 321 的十进制值为&#xff…...

java项目验证码登录

1.依赖 导入hutool工具包用于创建验证码 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.5.2</version></dependency> 2.测试 生成一个验证码图片&#xff08;生成的图片浏览器可…...

手写MVVM框架-环境搭建

项目使用 webpack 进行进行构建&#xff0c;初始化步骤如下: 1.创建npm项目执行npm init 一直下一步就行 2.安装webpack、webpack-cli、webpack-dev-server&#xff0c;html-webpack-plugin npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin 3.配置webpac…...

2025年2月2日(网络编程 tcp)

tcp 循环服务 import socketdef main():# 创建 socket# 绑定tcp_server socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_server.bind(("", 8080))# socket 转变为被动tcp_server.listen(128)while True:# 产生专门为链接进来的客户端服务的 socketprint(&qu…...

【Docker项目实战】使用Docker部署MinIO对象存储(详细教程)

【Docker项目实战】使用Docker部署MinIO对象存储 前言一、 MinIO介绍1.1 MinIO简介1.2 主要特点1.3 主要使用场景二、本次实践规划2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、下载MinIO镜像五、…...

使用ollama本地部署Deepseek r1

1、下载ollama 在浏览器地址输入&#xff1a;https://ollama.com/ 选择windows版本的下载 2、安装ollama 3、运行ollama 安装完成后&#xff0c;打开命令行工具win r 在命令行输入&#xff1a;ollama 4、使用ollama下载并部署Deepseed r1 在ollama网站&#xff0c;下载…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…...