Verilog流水线CPU设计(超详细)

16位流水线CPU设计(部分) 计算机组成原理实验:16位流水线CPU设计 阅读详情
AI摘要

本文详细介绍Verilog流水线CPU设计,包括设计目的、器材、总体方案等。将处理过程分为五级,阐述数据通路。针对数据冒险和控制冒险提出解决策略,如寄存器堆写操作提前、内部前推等。还给出各模块详细设计及仿真分析,验证设计可解决冒险问题。

上篇:Verilog单周期CPU设计(超详细)
本篇完整工程下载链接,已于19.12.17更新

一、设计目的与要求

1.1 实验内容

  1. 本实例所设计CPU的指令格式的拟定。
  2. 基本功能部件的设计与实现。
  3. CPU各主要功能部件的设计与实现。
  4. CPU的封装。
  5. 了解提高CPU性能的方法。
  6. 掌握流水线MIPS微处理器的工作原理。
  7. 理解数据冒险、控制冒险的概念以及流水线冲突的解决方法。
  8. 掌握流水线MIPS微处理器的测试方法。

1.2 实验要求

  1. 至少支持add、sub、and、or、addi、andi、ori、lw、sw、beq、bne十一条指令。
  2. 采用5级流水线技术,具有数据前推机制。

1.3 实验创新

  1. 寄存器堆的写操作提前半个时钟周期。
  2. 完成Lw指令的数据冒险的解决。
  3. 完成控制冒险的解决。

二、课程设计器材

2.1 硬件平台

无

2.2 软件平台

  1. 操作系统:Win 10。
  2. 开发平台:Vivado 2017.2。
  3. 编程语言:VerilogHDL硬件描述语言。

三、CPU逻辑设计总体方案

流水线是数字系统中一种提高系统稳定性和工作速度的方法,广泛应用于高档CPU的架构中。根据MIPS处理器的特点,将整体的处理过程分为取指令(IF)、指令译码(ID)、执行(EX)、存储器访问(MEM)和寄存器会写(WB)五级,对应多周期的五个处理阶段。一个指令的执行需要5个时钟周期,每个时钟周期的上升沿来临时,此指令所代表的一系列数据和控制信息将转移到下一级处理。
在这里插入图片描述
图3-1 流水线

3.1 数据通路

(1) IF级:取指令部分。
包括指令储存器和PC寄存器及其更新模块,负责根据PC寄存器的值从指令存储器中取出指令编码和对PC的值进行更新。
(2) ID级:指令译码部分。
根据独处的指令编码形成控制信号和读寄存器堆输出的寄存器的值。
流水线冒险检测也在该级进行,冒险检测电路需要上一条指令的MemRead,即在检测到冒险条件成立时,冒险检测电路产生stall信号清空ID/EX寄存器,插入一个流水线气泡。
(3) EX级:执行部分。
根据指令的编码进行算数或者逻辑运算或者计算条件分支指令的跳转目标地址。
此外LW、SW指令所用的RAM访问地址也是在本级上实现。控制信号有ALUCode、ALUSrcA、ALUScrB和RegDst,根据这些信号确定ALU操作、选择两个ALU操作数A、B,并确定目标寄存器。另外,数据转发也在该级完成。数据转发控制电路产生ForwardA和ForwardB两组控制信号。
(4) MEM级:存储器访问部分。
只有在执行LW、SW指令时才对存储器进行读写,对其他指令只起到一个周期的作用。该级只需存储器写操作允许信号MemWrite。
(5) WB级:寄存器堆写回部分。
该级把指令执行的结果回写到寄存器文件中。
该级设置信号MemtoReg和寄存器写操作允许信号RegWrite,其中MemtoReg决定写入寄存器的数据来自于MEM级上的缓冲值或来自于MEM级上的存储器。
在这里插入图片描述
在这里插入图片描述
图3.1-1 数据通路

3.2 MIPS指令格式

MIPS指令系统结构有MIPS-32和MIPS-64两种。本实验的MIPS指令选用MIPS-32。以下所说的MIPS指令均指MIPS-32。
MIPS的指令格式为32位。图3-3给出了MIPS指令的3种格式。
在这里插入图片描述

图3-2 MIPS指令格式

本实验只选取了11条典型的MIPS指令来描述CPU逻辑电路的设计方法。表3-1列出了本实验的所涉及到的11条MIPS指令。
在这里插入图片描述
R型指令的op均为0,具体操作由func指定。rs和rt是源寄存器号,rd是目的寄存器号。移位指令中使用sa指定移位位数。
I型指令的低16位是立即数,计算时需扩展到32位,依指令的不同需进行零扩展和符号扩展。

3.3 流水线CPU结构设计图

在这里插入图片描述
图3-4 流水线CPU总体结构图

图3-4是一个简单的基本上能够在流水线上完成所要求设计的指令功能的数据通路和必要的控制线路图。其中指令储存在指令储存器,数据储存在数据存储器。而且实现了数据冒险和控制冒险的解决方案。但是此结构仅解决了数据冒险,没有解决控制冒险,若要想解决控制冒险,需要把EX级的移位器和计算分支目标地址的加法器前移到ID。在下文中会给出具体的解决方法。

3.4 流水线CPU逻辑流程图

根据实验原理中的流水线CPU总体结构图,我们可以清楚的知道流水线CPU的设计应包括五级。其中为了运行整个CPU还需要加入一个顶层模块(MAIN)来调用这些模块,所以自然地,这些模块为顶层模块的子模块。设计流程逻辑图如下(左边为流水线寄存器组,右边为各级模块)。
在这里插入图片描述

3.5 变量命名

由于在流水线中,数据和控制信息将在时钟周期的上升沿转移到下一级,所以规定流水线转移变量命名为:名称_流水线级名称。

四、冒险解决策略

4.1 数据冒险

在基本流水线中相邻两条指令的前一条指令还没有更新目的寄存器时,后一条指令就已经先读取了该寄存器的旧值,使得指令的计算结果出现错误。这样相关的问题就称为数据冒险。下面给出本实验所使用的解决方法。

4.1.1 寄存器堆的写操作提前半个时钟周期

在未提前半周期时CPU中,指令在时钟周期结束时的上升沿将ID级寄存器的值锁存进ID/EX,或将ALU的计算结果更新寄存器的值。但是寄存器的读、写的操作时间实际上只有时钟周期的一半。因此可以把寄存器堆的写操作提前到时钟周期中间的下降沿完成。那么后半个时钟周期就可以将写入之后的值读出。这样做后,同一级的数据冒险得到解决。

4.1.2内部前推

运算指令的结果在EX级结束时,就已经锁存在EX/MEM的Rd中,然而寄存器的值在ID结束时就已经锁存在ID/EX,但在EX级才真正使用这些值。
所以为了支持内部前推,需在ALU的两个输入端之前,分别增加一个多路选择器和相应的数据通路,并检测处于EX级指令的两个源操作寄存器号是否和处于MEM级或WB级指令的目的寄存器号相等。下面给出检测条件。

  1. [条件a] E_Rs == EX/MEM.Rd,
    判断EX级指令的rs字段是否和MEM级指令的目的寄存器号相同
  2. [条件b] E_Rs == MEM/WB.Rd,
    判断EX级指令的rs字段是否和WB级指令的目的寄存器号相同
  3. [条件c] (E_Rt == EX/MEM.Rd) & ((E_Inst == I_add) | (E_Inst == I_sub) | (E_Inst == I_and) | (E_Inst == I_or) | (E_Inst == sw) | (E_Inst == beq) | (E_Inst == bne))
    判断EX级指令的rt字段是否和MEM级指令的目的寄存器号相同
  4. [条件d] (E_Rt == MEM/WB.Rd) & ((E_Inst == I_add) | (E_Inst == I_sub) | (E_Inst == I_and) | (E_Inst == I_or) | (E_Inst == sw) | (E_Inst == beq) | (E_Inst == bne))
    判断EX级指令的rt字段是否和WB级指令的目的寄存器号相同

同时应该考虑以下几种特殊情况。

  1. 某些指令可能不写回寄存器,例如sw和beq指令,或者某些指令的写信号被关闭。所以还需检测处于MEM级或WB级指令的寄存器堆写使能信号M_Wreg或W_Wreg是否有效。
  2. 寄存器$0始终为0,不必考虑在$0上产生的数据冒险,即第三条指令分别与第一条、第二条指令存在数据冒险。按照执行逻辑,当第三条指令处于EX级时应选择处于MEM级的第二条指令的前推。而不能选择第一条前推。所以在判断逻辑模块的代码实现时,应先判断相邻两条指令是否存在数据冒险。

4.1.3 lw指令的数据冒险

内部前推有显而易见的局限性,因为内部前推必须要求前一条指令在EX结束时更新,但是LW指令最早只能在WB级读出寄存器的值。因此无法及时提供给下一条指令的EX级使用。
分析流水线时序图,可以发现lw指令的下一条指令,需要阻塞一个时钟周期,才能确保该指令能获得正确的操作数值,下面给出具体解决方法。
检测是否存在lw指令的数据冒险。
检测单元仍放置于CONUNIT部件内,且Reg2reg信号可以唯一区分lw指令和其他指令。检测条件可写为:
((Rs == E_Rd) | (Rt == E_Rd)) & (E_Reg2reg == 0) & (E_Rd != 0) & (E_Wreg == 1)

暂停流水线的实现:
我们可以通过插入气泡来暂停流水线,也即是关闭PC寄存器和IF/ID流水线寄存器组的写使能信号,而且将ID/EX流水线寄存器组的Clrn端口信号清零。

4.2 控制冒险

在处理beq和bne指令时,条件分支指令或者跳转指令的后续指令有可能在目标地址形成之前或分支条件形成之前就已经进入流水线。这样相关的问题就称为控制冒险。下面给出本实验所使用的解决方法。

4.2.1 缩短分支的延迟

流水线中,尽早完成分支的决策,可以减少性能损失假设图 中M_Z信号和分支目标地址的输出阶段从MEM级前移到EX级,那么图 中(下图)的指令序列只需要被阻塞2个时钟周期就能解决控制冒险因为正确的目标地址在EX级形成,EX级结束时就更新了PC寄存器。
在这里插入图片描述
图4.2-1 分支指令

之后通过如下四步解决控制冒险:

  • 在条件分支指令处于EX级时,判断分支条件是否成立
  • 若成立,则控制部件CONUNIT的STALL端口(流水线阻塞)输出高电平,IF/ID和ID/EX流水线寄存器组的Clrn端口输入为低电平
  • 在该时钟周期结束时,IF/ID和ID/EX流水线寄存器组的内容清0,即变为两条空指令
  • 这样在下一个时钟周期开始时,正确的目标指令处于IF级,ID级和EX级都是编码为全0的空指令,条件分支指令进入到MEM级

五、 模块详细设计

5.1取指令部分(IF)

5.1.1 PCAdd4

  • 所处位置
    -在这里插入图片描述

  • 模块功能
    作为PC寄存器的更新信号。

  • 实现思路
    由于每条指令32位,所以增加一个32位加法器,固定与32位的立即数4进行相加,且得到的结果在当前时钟信号的上升沿更新进PC寄存器。

  • 引脚及控制信号
    IF_Addr:当前指令地址,输入端口(IF内循环)
    IF_PCadd4:下一条指令地址,输出端口

  • 主要实现代码
    1.PCAdd4

module PCadd4(PC_o,PCadd4);
input [31:0] PC_o;//偏移量
output [31:0] PCadd4;//新指令地址
CLA_32 cla32(PC_o,4,0, PCadd4, Cout);
endmodule

1.CLA_32

module CLA_32(X, Y, Cin, S, Cout);
input [31:0] X, Y; 
input Cin;   
output [31:0] S;
output Cout;
wire Cout0, Cout1, Cout2, Cout3, Cout4, Cout5, Cout6;    
CLA_4 add0 (X[3:0], Y[3:0], Cin, S[3:0], Cout0);
CLA_4 add1 (X[7:4], Y[7:4], Cout0, S[7:4], Cout1);
CLA_4 add2 (X[11:8], Y[11:8], Cout1, S[11:8], Cout2);
CLA_4 add3 (X[15:12], Y[15:12], Cout2, S[15:12], Cout3);
CLA_4 add4 (X[19:16], Y[19:16], Cout3, S[19:16], Cout4);
CLA_4 add5 (X[23:20], Y[23:20], Cout4, S[23:20], Cout5);
CLA_4 add6 (X[27:24], Y[27:24], Cout5, S[27:24], Cout6);
CLA_4 add7 (X[31:28], Y[31:28], Cout6, S[31:28], Cout);
Endmodule

1.CLA_4

module CLA_4(X, Y, Cin, S, Cout);
input [3:0] X;
input [3:0] Y;
input Cin;
output [3:0] S;
output Cout;
and get_0_0_0(tmp_0_0_0, X[0], Y[0]);
or get_0_0_1(tmp_0_0_1, X[0], Y[0]);
and get_0_1_0(tmp_0_1_0, X[1], Y[1]);
or get_0_1_1(tmp_0_1_1, X[1], Y[1]);

and get_0_2_0(tmp_0_2_0, X[2], Y[2]);
or get_0_2_1(tmp_0_2_1, X[2], Y[2]);
and get_0_3_0(tmp_0_3_0, X[3], Y[3]);
or get_0_3_1(tmp_0_3_1, X[3], Y[3]);
and get_1_0_0(tmp_1_0_0, ~tmp_0_0_0, tmp_0_0_1);
xor getS0(S0, tmp_1_0_0, Cin);
and get_1_1_0(tmp_1_1_0, ~tmp_0_1_0, tmp_0_1_1);
not get_1_1_1(tmp_1_1_1, tmp_0_0_0);
nand get_1_1_2(tmp_1_1_2, Cin, tmp_0_0_1);
nand get_2_0_0(tmp_2_0_0, tmp_1_1_1, tmp_1_1_2);
xor getS1(S1, tmp_1_1_0, tmp_2_0_0);
and get_1_2_0(tmp_1_2_0, ~tmp_0_2_0, tmp_0_2_1);
not get_1_2_1(tmp_1_2_1, tmp_0_1_0);
nand get_1_2_2(tmp_1_2_2, tmp_0_1_1, tmp_0_0_0);
nand get_1_2_3(tmp_1_2_3, tmp_0_1_1, tmp_0_0_1, Cin);
nand get_2_1_0(tmp_2_1_0, tmp_1_2_1, tmp_1_2_2, tmp_1_2_3);
xor getS2(S2, tmp_1_2_0, tmp_2_1_0);
and get_1_3_0(tmp_1_3_0, ~tmp_0_3_0, tmp_0_3_1);
not get_1_3_1(tmp_1_3_1, tmp_0_2_0);
nand get_1_3_2(tmp_1_3_2, tmp_0_2_1, tmp_0_1_0);
nand get_1_3_3(tmp_1_3_3, tmp_0_2_1, tmp_0_1_1, tmp_0_0_0);
nand get_1_3_4(tmp_1_3_4, tmp_0_2_1, tmp_0_1_1, tmp_0_0_1, Cin); 
nand get_2_2_0(tmp_2_2_0, tmp_1_3_1, tmp_1_3_2, tmp_1_3_3, tmp_1_3_4);
xor getS3(S3, tmp_1_3_0, tmp_2_2_0);
not get_1_4_0(tmp_1_4_0, tmp_0_3_0);
nand get_1_4_1(tmp_1_4_1, tmp_0_3_1, tmp_0_2_0);
nand get_1_4_2(tmp_1_4_2, tmp_0_3_1, tmp_0_2_1, tmp_0_1_0);
nand get_1_4_3(tmp_1_4_3, tmp_0_3_1, tmp_0_2_1, tmp_0_1_1, tmp_0_0_0);
nand get_1_4_4(tmp_1_4_4, tmp_0_3_1, tmp_0_2_1, tmp_0_1_1, tmp_0_0_1, Cin);
nand getCout(Cout, tmp_1_4_0, tmp_1_4_1, tmp_1_4_2, tmp_1_4_3,tmp_1_4_4);
assign S = {
   
   S3,S2,S1,S0};
endmodule

5.1.2 PC

  • 所处位置
    在这里插入图片描述

  • 模块功能
    用于给出指令在指令储存器中的地址,且当发生数据冒险时,需要保持PC寄存器不变。

  • 实现思路
    为实现稳定输出,在时钟信号的上升沿更新。在发生Lw指令的数据冒险和控制冒险时,PC寄存器应该消除错误指令,而且需要在此周期关闭PC寄存器。

  • 引脚及控制信号
    En:控制PC寄存器的开启和关闭状态,外部输入信号。
    stall:判断是否发生Lw指令数据冒险,输入信号。
    Clk:时钟周期,输入信号
    Clrn:当存在Lw指令的数据冒险和控制冒险时为零,输入信号。
    IF_Result目标地址,输入信号。
    IF_Addr:指令地址,输出信号。

  • 主要实现代码

module PC(IF_Result,Clk,En,Clrn,IF_Addr,stall);
input [31:0]IF_Result;
input Clk,En,Clrn,stall;
output [31:0] IF_Addr;
wire En_S;
assign En_S=En&~stall;
D_FFEC32 pc(IF_Result,Clk,En_S,Clrn,IF_Addr);
endmodule 

5.1.3 INSTMEM

  • 所处位置
    在这里插入图片描述

  • 模块功能
    依据当前pc,读取指令寄存器中相对应地址Addr[6:2]的指令。

  • 实现思路
    将pc的输入作为敏感变量,当pc发生改变的时候,则进行指令的读取,根据相关的地址,输出指令寄存器中相对应的指令,且在设计指令的时候,要用到12条给出的指令且尽量合理。

  • 引脚及控制信号
    IF_Addr:指令地址,输入信号
    IF_Inst:指令编码,输出信号

  • 主要实现代码

module INSTMEM(Addr,Inst);//指令存储器
input[31:0]Addr;
output[31:0]Inst;
wire[31:0]Rom[31:0];
assign Rom[5'h00]=32'h20010008;//addi $1,$0,8 $1=8 001000 00000 00001 0000000000001000
assign Rom[5'h01]=32'h3402000C;//ori $2,$0,12 $2=12
assign Rom[5'h02]=32'h00221820;//add $3,$1,$2 $3=20//数据冒险
assign Rom[5'h03]=32'h00412022;//sub $4,$2,$1 $4=4
assign Rom[5'h04]=32'h00222824;//and $5,$1,$2
assign Rom[5'h05]=32'h00223025;//or $6,$1,$2
assign Rom[5'h06]=32'h14220006;//bne $1,$2,6//00010100001000010000000000000110
assign Rom[5'h07]=32'h00221820;//add $3,$1,$2 $3=20
assign Rom[5'h08]=32'h00412022;//sub $4,$2,$1 $4=4
assign Rom[5'h09]=32'h10220002;// beq $1,$2,2
assign Rom[5'h0A]=32'h0800000D;// J 0D 
assign Rom[5'h0B]=32'hXXXXXXXX;
assign Rom[5'h0C]=32'hXXXXXXXX;
assign Rom[5'h0D]=32'hAD02000A;// sw $2 
Verilog实现MIPS的5级流水线cpu设计(Modelsim仿真) Verilog实现IMPS的5级流水线cpu设计 本篇文章是在功能上实现cpu设计,而非结构上实现。结构上实现可以跳转到(此为个人推荐): Verilog流水线CPU设计(超详细) 此外有与本文章配套的资源,文章中不懂的地方可以跳转到: IMPS五级流水线cpu的制作 一、实验内容 1.1:实验目的 (1)CPU各主要功能部件的实现 (2)CPU的封装 (3)了解提高CPU性能的方法 (4)掌... 阅读详情

相关推荐

Verilog单周期CPU设计(超详细)

实验 单周期CPU一、设计目的与目标实验内容实验要求二、课程设计器材硬件平台软件平台三、 CPU逻辑设计总体方案指令模块MIPS指令格式指令处理流程数据通路总体结构图设计流程逻辑图四、模块详细设计PCAdd4PCINSTMEMDATAMEMSHIFTER32_L2SHIFTER_COMBINATIONMUX4X32MUX2X5EXT16T32MUX2X32CONUNITREGFILEALUSing...

Ace Cheney的博客 9万+

基于Verilog的流水线CPU设计

MIPS五级流水线CPU设计。

qq_45945307的博客 2902

Verilog十大基本功1(流水线设计Pipeline Design)

需求说明:Verilog设计基础 内容       :流水线设计 来自       :时间的诗 流水线设计 前言: 本文从四部分对流水线设计进行分析,具体如下: 第一部分什么是流水线 第二部分什么时候用流水线设计 第三部分使用流水线的优缺点 第四部分流水线加法器举例 第一 什么是流水线 流水线设计就是将组合逻辑系统地分割

时间的诗 5万+

用Verilog搭建RISC-V架构流水线CPU

单周期CPU的实现从某种意义上来说是为了给流水线CPU打基础,毕竟单周期CPU无论是理论还是工程实现上的意义都不大,将CPU所有的工作全部交给一个时钟周期搞定,未免有些浪费本就珍贵的硬件资源,为了体现分治策略思想,同时更重要的是为了提升CPU的主频以实现更高的性能,在硬件条件不能更改时,流水线是一种非常经典的性能优化策略。

paticita的博客 7967

三步教你用Verilog写一个CPU:第一步

  三步教你用Verilog写一个CPU 第一步:小试牛刀       也许在不少人眼里,这个世界有两座难以企及的大山,一座是操作系统,还有一座就是CPU。无可否认,无论开发一个操作系统还是做一个CPU都是一件极其浩大的工程,需要一个优秀的团队前赴后继的努力。我相信有不少想涉足这两方面的人开始的时候都会有种无从下手的感觉,但是,经过我这一系列CPU的教程之后,我有十足把握,你肯定会...

MarshalRUAN 1万+

RISC-V 流水线 CPU 设计 Verilog

实验设计的是五段式流水线 CPU,分别为 IF(取指),ID(指令译码),EX(执行),MEM(访存),WB(写回)五个阶段,并且时钟周期由所有指令耗时最长的阶段决定。同时还有一个比较关键的在于需要解决结构冒险(寄存器可能同时需要读、写),控制冒险(跳转指令可能会改变指令顺序,但流水线读取每次是先读取静态 PC, 即 PC + 4),以及数据冒险(在本实验中是 RAW,即还未写回就以及需要进行读取)。以上这些问题需要通过设计转发单元,以及阻塞冲刷信号等等来实现。

weixin_69763109的博客 4940

【Verilog项目】计算机体系结构-五级流水线CPU

本文涉及实验是电子科技大学2021计算机体系结构课程实验。内容均为原创

weixin_45151415的博客 3651

基于MIPS架构的5级流水线CPU设计与Verilog实现

在现代计算机体系结构领域,MIPS(Microprocessor without Interlocked Pipeline Stages,即无互锁流水级微处理器)架构因其简洁和高效而占据了重要的地位。MIPS架构最初由MIPS计算机系统公司于1981年开发,旨在提供一种能够适用于各种计算环境的处理器设计。Verilog是一种硬件描述语言(HDL),它允许设计者以文本形式描述电子系统的结构和行为。Verilog语法包括模块定义、端口声明、信号赋值、数据流、行为描述以及各种构造语句。

weixin_42608299的博客 1006

基于Verilog实现的MIPS五级流水线CPU设计

简介:本项目通过Verilog硬件描述语言实现了一个五级流水线的MIPS CPU,实现了包括基本和高级指令在内的20条指令。介绍了Verilog语言在复杂集成电路设计中的应用,五级流水线的设计原则和实现,以及MIPS指令集的基础和扩展。同时,探讨了处理数据和控制冲突的策略,以及CPU中的寄存器和内存管理,还包括了错误检测与异常处理机制。该项目不仅加深了对MIPS架构和计算机系统工作原理的理解,也提高了硬件设计的技术能力。

weixin_30533301的博客 1426

基于Verilog的流水线CPU设计与实现

Verilog中的基本设计单元是module,它封装了输入输出接口和内部逻辑。一个典型的模块定义如下:case (op)// ADD// SUB// AND// ORendcaseendendmodule逐行逻辑分析:第1–6行:模块声明与端口列表。使用input和output关键字明确方向,[31:0]表示32位宽总线。第7行:output reg说明该输出在always块中赋值,需声明为reg类型,尽管最终综合成组合逻辑。

weixin_35906794的博客 1244

数字电路课程CPU设计(verilog完整代码+报告+设计图)

数字电路课程大作业,花了三天写完了一个比较简单版本的(16位二进制命令,8位数据,可实现加减绝对值等多种功能),自主设计CPU自主编写代码,附加英文report,开发环境ISE(课堂上认真做的和抄的分数差不多,所以来这里赚点积分吧,也不荒废做了几天的苦力,本科生可参考)

ESP32-S3驱动雨滴传感器实战:从原理到ADC/GPIO双模式数据采集

本文详细介绍了ESP32-S3驱动雨滴传感器的实战教程,涵盖其工作原理及ADC/GPIO双模式数据采集方法。通过解析传感器利用水的导电性检测雨量的核心机制,提供了完整的硬件连接方案与软件驱动代码,包括模拟量(AO)的ADC读取和数字量(DO)的GPIO读取,并附有调试技巧,帮助开发者快速实现雨滴检测功能。

weixin_32005771的博客 154

【同花顺公式编辑教程】第4章 功能函数

本章节主要给出大部分能够运行且常用的同花顺指标编辑器提供的函数。其中,计算类函数不作演示,绘图类函数提供示例及示例运行结果。

LiaoYi2016218的博客 2万+

音视频入门:H264、H265概念总结

添加链接描述 什么是H.264与H.265 H.264与H.265都是视频压缩格式,由于视频本身的码流太大,所以需要经过压缩然后再通过网络进行传输。H.264是目前比较主流的压缩算法,像视频会议设备一般都采用这个编码格式。基础的H.264可以支持在1M带宽下传输720P30帧/秒的图像;H.264 HIGH PROFILE支持在512K带宽下传输720P30帧/秒的图像。 H.265是比较新的压缩算法,可以更一步提高压缩比,随着我们现在生活中出现的视频格式越来越大(比如现在基本都是1080P甚至4K的显示器

weixin_40673765的博客 8936

Windows10完美驱动Apple Studio Display全攻略:从雷电转接到亮度调节(附N卡兼容列表)

本文详细介绍了在Windows10系统下如何完美驱动Apple Studio Display显示器,包括雷电接口转接方案、BootCamp驱动安装及NVIDIA显卡兼容性测试。特别推荐GTX 1660 Super等显卡,提供5K@60Hz稳定输出,并分享色彩管理及日常使用技巧,帮助用户充分发挥这款苹果显示器的性能。

weixin_29284657的博客 1088

YOLOv8+BiFPN双向特征金字塔:多尺度目标检测精度提升28%的实战教程

双向特征金字塔网络(BiFPN)是一种强化多尺度特征融合支持“自顶向下+自底向上”的双向特征流动,同时保留不同尺度的细节信息;引入加权融合机制,自动学习不同特征的重要性权重;裁剪冗余节点,在轻量化的同时提升融合效率。

m0_64661770的博客 492

【计算机视觉 | MMDetection】关于mmdetection如何计算参数量、计算量和速度FPS

【计算机视觉 | MMDetection】关于mmdetection如何计算参数量、计算量和速度FPS

wzk4869的博客 3020

①电子产品拆解分析-暖手宝

电子产品拆解分析-暖手宝 ①按键三档调温暖手; ②长按进入氛围呼吸灯; ③安卓接口充电以及支持USB输出;

a6662580的博客 5289

仿真学习系列(四十七):Sigrity仿真之直流压降与电流密度

在现代电子设计中,电源网络的设计和分析对于保证电路的稳定性至关重要。直流压降(IR-Drop)和电流密度是评估电源网络性能的关键参数,尤其是在高频和高速电路中。它们直接影响到设备的工作稳定性与效率。通过Sigrity的仿真工具,可以深入分析和优化这些电源特性,从而确保系统的可靠性。 本节将介绍直流压降和电流密度的基本概念,以及如何在Sigrity中使用PowerDC模块进行相关仿真。

案例文章,高速信号 508

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

上一篇: Python实现支持人机对战的五子棋软件(超详细)
下一篇: import geatpy 报错以及geatpy安装报错问题总结
Ace Cheney
博客等级 码龄9年 542粉丝 27原创
评论 53
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ace Cheney

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值