【FPGA零基础学习之旅#7】BCD计数器设计

news2024/11/7 18:00:24

🎉欢迎来到FPGA专栏~BCD计数器设计


  • ☆* o(≧▽≦)o *☆~我是小夏与酒🍹
  • 博客主页:小夏与酒的博客
  • 🎈该系列文章专栏:FPGA学习之旅
  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
  • 📜 欢迎大家关注! ❤️
    FPGQ2

CSDN

🎉 目录-BCD计数器设计

  • 一、效果演示
  • 二、BCD码基础知识
  • 三、BCD计数器Verilog实现
  • 四、级联BCD计数器实现
    • 4.1 Verilog实现
    • 4.2 ip核实现

遇见未来

一、效果演示

顶层模块中的BCD模块级联:
Verilog实现:
结果1
调用ip核实现:
ip

当计数到12‘h999时,产生一个进位输出:
结果2

二、BCD码基础知识

BCD 码中最常用的是 8421 码,其各个 bit 权值分别是 8d、4d、2d、1d;同理 5421 码各位的权依次为 5d、4d、2d、1d。5421 码特点是最高位连续 5 个 0 后连续 5 个 1,故其当计数器采用这种编码时,最高位可产生对称方波输出;余 3 码是在 8421 码上加 0011b 得出来的;格雷码的特点是任意两个相邻的代码只有一位二进制数不同,编码格式不唯一;余 3 循环码具有格雷码的特点并且编码的首尾可以连接来进行循环,这样可用反馈移位寄存器来实现,硬件实现简单。

在实际使用中如不特指 BCD 码格式,则均为 8421 码。通过以上介绍将十进制 895 转换为BCD 码就是 1000_1001_0101,同理若将 BCD 码 1001_0110_0100 转换为十进制数即为 964。

BCD 码的主要应用之一就是数码管,假设要将十进制数 158 显示,一般解决办法是把需要显示的十进制数的个、十、百、千位数等进行拆分,即把 158 拆分出 1、5、8,然后查出对应的数码管显示段码再送去给数码管连接的 IO 口。这个过程可以进行下面的运算:先进行除法运算 158/100 得出百位 1,再取余 158%100 = 58 后继续进行除法运算 58 / 10 得出十位5,再进行一次取余 158%10 ,得到个位 8。以上过程可以看出需要除法,但是由于除法运算是比较消耗计算时间导致整体需要的指令周期太久。但是如果先将其转换为 BCD 码,则可大幅度减少运算时间。

三、BCD计数器Verilog实现

我们使用Verilog HDL实现一个BCD计数器。

一个BCD计数模块结构如下:
模块结构
其中,各端口信号的含义如下表所示:

端口信号I/O功能
Clkinput50M系统时钟
Rst_ninput全局复位
Cininput进位输入信号
Coutoutput进位输出信号
qoutput计数值输出

对于计数过程,最大计数值设定为4‘d9

//执行计数过程
always@(posedge Clk or negedge Rst_n)begin
	if(!Rst_n)
		cnt <= 4'd0;
	else if(Cin == 1'b1)begin
		if(cnt == 4'd9)
			cnt <= 4'd0;
		else
			cnt <= cnt + 1'b1;
	end
	else
	cnt <= cnt;	
end

📜需要注意的是,只有当计数值达到4’d9,且Cin信号为高电平时,Cout才会产生一个高电平信号。

Verilog HDL代码:

module BCD_Counter(
	input		  Clk,		//系统时钟信号
	input 		  Rst_n,	//系统复位信号
	input 		  Cin,		//进位输入信号
	output 	reg	  Cout,		//进位输出信号
	output	[3:0] q			//计数器值
);

	reg [3:0]cnt;
	
	//执行计数过程
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			cnt <= 4'd0;
		else if(Cin == 1'b1)begin
			if(cnt == 4'd9)
				cnt <= 4'd0;
			else
				cnt <= cnt + 1'b1;
		end
		else
		cnt <= cnt;	
	end

	//产生进位输出信号
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			Cout <= 1'b0;
		else if(cnt == 4'd9 && Cin == 1'b1)
			Cout <= 1'b1;
		else
			Cout <= 1'b0;
	end

	assign q = cnt;

endmodule

RTL视图:

RTL视图
在仿真测试过程中,为了便于观察,我们产生占空比为1:5的Cin信号:

repeat(30)begin
			Cin = 1'b1;
			#(`clock_period*1);
			Cin = 1'b0;
			#(`clock_period*5);
		end

测试激励文件:

`timescale 1ns/1ns
`define clock_period 20

module BCD_Counter_tb;
	
	reg Clk;
	reg Rst_n;
	reg Cin;
	
	wire Cout;
	wire [3:0]q;
	
	BCD_Counter BCD_Counter0(
		.Clk(Clk),		//系统时钟信号
		.Rst_n(Rst_n),	//系统复位信号
		.Cin(Cin),		//进位输入信号
		.Cout(Cout),		//进位输出信号
		.q(q)			//计数器值
	);
	
	initial Clk = 1;
	always#(`clock_period/2) Clk = ~Clk;
	
	initial begin
		Rst_n = 1'b0;
		Cin = 1'b0;
		#(`clock_period*20);
		
		Rst_n = 1;
		#(`clock_period*20);
		
		repeat(30)begin
			Cin = 1'b1;
			#(`clock_period*1);
			Cin = 1'b0;
			#(`clock_period*5);
		end
		
		#(`clock_period*20);
		$stop;
	end
	
endmodule

仿真结果:

仿真结果

四、级联BCD计数器实现

BCD计数器的级联RTL视图:
RTL1
在上述设计过程中,一个BCD计数器的计数范围为:4'd0~4'd9,即4'h0~4'h9
在此使用了三个BCD计数器进行级联,因此顶层输出的hex格式数据范围为000~999

4.1 Verilog实现

在顶层文件中调用已编写好的BCD模块:

module BCD_Counter_top(
	input					Clk,		//系统时钟信号
	input 				Rst_n,	//系统复位信号
	input 				Cin,		//进位输入信号
	output 				Cout,		//进位输出信号
	output	[11:0]	q			//计数器值
);
	
	wire Cout0;
	wire Cout1;
	wire Cout2;
	
	wire [3:0]q0;
	wire [3:0]q1;
	wire [3:0]q2;
	
	BCD_Counter BCD_Counter0(
		.Clk(Clk),		
		.Rst_n(Rst_n),	
		.Cin(Cin),		
		.Cout(Cout0),		
		.q(q0)			
	);
	
	BCD_Counter BCD_Counter1(
		.Clk(Clk),		
		.Rst_n(Rst_n),	
		.Cin(Cout0),		
		.Cout(Cout1),		
		.q(q1)		
	);
	
	BCD_Counter BCD_Counter2(
		.Clk(Clk),		
		.Rst_n(Rst_n),	
		.Cin(Cout1),		
		.Cout(Cout2),		
		.q(q2)			
	);

	assign Cout = Cout2;
	
	assign q = {q2,q1,q0};

endmodule

由于级联的BCD计数器计数范围较大,在编写测试激励文件的时候可以直接把Cin信号置为高电平

`timescale 1ns/1ns
`define clock_period 20

module BCD_Counter_top_tb;
	
	reg Clk;
	reg Rst_n;
	reg Cin;
	
	wire Cout;
	wire [11:0]q;
	
	BCD_Counter_top BCD_Counter_top0(
		.Clk(Clk),		//系统时钟信号
		.Rst_n(Rst_n),	//系统复位信号
		.Cin(Cin),		//进位输入信号
		.Cout(Cout),	//进位输出信号
		.q(q)				//计数器值
	);
	
	initial Clk = 1;
	always#(`clock_period) Clk = ~Clk;
	
	initial begin
		Rst_n = 0;
		Cin = 1'b0;
		#(`clock_period*10)
		
		Rst_n = 1;
		#(`clock_period*5)
		
		Cin = 1'b1;
		#(`clock_period*5000)
	
		$stop;
	
	end

endmodule

仿真结果如下图:
仿真问题
从仿真结果中可以看出来:Cout信号延迟了三个系统时钟周期才出现,设计存在错误,不符合设计要求。

加入具体波形,发现BCD_Counter0BCD_Counter1BCD_Counter2的输出已经出现系统时钟周期的延迟:
三个延迟
在基础的BCD_Counter模块中,Cout信号的产生使用了D触发器,所以造成了一拍的延迟。为了消除延迟效果,需要使用组合逻辑电路

...
output Cout,		//进位输出信号
...
//产生进位输出信号
assign Cout = (cnt == 4'd9 && Cin == 1'b1);
...

即:

module BCD_Counter(
	input			Clk,		//系统时钟信号
	input 			Rst_n,	//系统复位信号
	input 			Cin,		//进位输入信号
	output 	  		Cout,		//进位输出信号
	output	[3:0]	q			//计数器值
);

	reg [3:0]cnt;
	
	//执行计数过程
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			cnt <= 4'd0;
		else if(Cin == 1'b1)begin
			if(cnt == 4'd9)
				cnt <= 4'd0;
			else
				cnt <= cnt + 1'b1;
		end
		else
		cnt <= cnt;	
	end

	//产生进位输出信号
	assign Cout = (cnt == 4'd9 && Cin == 1'b1);

	assign q = cnt;

endmodule

重新仿真,计数结果正确:
正确

4.2 ip核实现

使用ip核创建计数器的过程:【FPGA零基础学习之旅#6】ip核基础知识之计数器。

首先使用ip核创建一个计数器,在此步骤勾选同步复位:

同步复位

ip核生成代码如下:

// megafunction wizard: %LPM_COUNTER%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: LPM_COUNTER 

// ============================================================
// File Name: Counter.v
// Megafunction Name(s):
// 			LPM_COUNTER
//
// Simulation Library Files(s):
// 			lpm
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.0.0 Build 156 04/24/2013 SJ Full Version
// ************************************************************


//Copyright (C) 1991-2013 Altera Corporation
//Your use of Altera Corporation's design tools, logic functions 
//and other software and tools, and its AMPP partner logic 
//functions, and any output files from any of the foregoing 
//(including device programming or simulation files), and any 
//associated documentation or information are expressly subject 
//to the terms and conditions of the Altera Program License 
//Subscription Agreement, Altera MegaCore Function License 
//Agreement, or other applicable license agreement, including, 
//without limitation, that your use is for the sole purpose of 
//programming logic devices manufactured by Altera and sold by 
//Altera or its authorized distributors.  Please refer to the 
//applicable agreement for further details.


// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module Counter (
	cin,
	clock,
	sclr,
	cout,
	q);

	input	  cin;
	input	  clock;
	input	  sclr;
	output	  cout;
	output	[3:0]  q;

	wire  sub_wire0;
	wire [3:0] sub_wire1;
	wire  cout = sub_wire0;
	wire [3:0] q = sub_wire1[3:0];

	lpm_counter	LPM_COUNTER_component (
				.cin (cin),
				.clock (clock),
				.sclr (sclr),
				.cout (sub_wire0),
				.q (sub_wire1),
				.aclr (1'b0),
				.aload (1'b0),
				.aset (1'b0),
				.clk_en (1'b1),
				.cnt_en (1'b1),
				.data ({4{1'b0}}),
				.eq (),
				.sload (1'b0),
				.sset (1'b0),
				.updown (1'b1));
	defparam
		LPM_COUNTER_component.lpm_direction = "UP",
		LPM_COUNTER_component.lpm_modulus = 10,
		LPM_COUNTER_component.lpm_port_updown = "PORT_UNUSED",
		LPM_COUNTER_component.lpm_type = "LPM_COUNTER",
		LPM_COUNTER_component.lpm_width = 4;


endmodule

// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: ACLR NUMERIC "0"
// Retrieval info: PRIVATE: ALOAD NUMERIC "0"
// Retrieval info: PRIVATE: ASET NUMERIC "0"
// Retrieval info: PRIVATE: ASET_ALL1 NUMERIC "1"
// Retrieval info: PRIVATE: CLK_EN NUMERIC "0"
// Retrieval info: PRIVATE: CNT_EN NUMERIC "0"
// Retrieval info: PRIVATE: CarryIn NUMERIC "1"
// Retrieval info: PRIVATE: CarryOut NUMERIC "1"
// Retrieval info: PRIVATE: Direction NUMERIC "0"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: PRIVATE: ModulusCounter NUMERIC "1"
// Retrieval info: PRIVATE: ModulusValue NUMERIC "10"
// Retrieval info: PRIVATE: SCLR NUMERIC "1"
// Retrieval info: PRIVATE: SLOAD NUMERIC "0"
// Retrieval info: PRIVATE: SSET NUMERIC "0"
// Retrieval info: PRIVATE: SSET_ALL1 NUMERIC "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: nBit NUMERIC "4"
// Retrieval info: PRIVATE: new_diagram STRING "1"
// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
// Retrieval info: CONSTANT: LPM_DIRECTION STRING "UP"
// Retrieval info: CONSTANT: LPM_MODULUS NUMERIC "10"
// Retrieval info: CONSTANT: LPM_PORT_UPDOWN STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_COUNTER"
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "4"
// Retrieval info: USED_PORT: cin 0 0 0 0 INPUT NODEFVAL "cin"
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
// Retrieval info: USED_PORT: cout 0 0 0 0 OUTPUT NODEFVAL "cout"
// Retrieval info: USED_PORT: q 0 0 4 0 OUTPUT NODEFVAL "q[3..0]"
// Retrieval info: USED_PORT: sclr 0 0 0 0 INPUT NODEFVAL "sclr"
// Retrieval info: CONNECT: @cin 0 0 0 0 cin 0 0 0 0
// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
// Retrieval info: CONNECT: @sclr 0 0 0 0 sclr 0 0 0 0
// Retrieval info: CONNECT: cout 0 0 0 0 @cout 0 0 0 0
// Retrieval info: CONNECT: q 0 0 4 0 @q 0 0 4 0
// Retrieval info: GEN_FILE: TYPE_NORMAL Counter.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL Counter.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL Counter.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL Counter.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL Counter_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL Counter_bb.v TRUE
// Retrieval info: LIB_FILE: lpm

创建一个顶层文件,并在顶层中调用ip核实现级联:

module Counter_ip_top(
	input 			Clk,
	input 			Rst_n,
	input 			Cin,
	output 			Cout,
	output [11:0]	q
);

	wire Cout0;
	wire Cout1;
	wire Cout2;
	
	wire [3:0]q0;
	wire [3:0]q1;
	wire [3:0]q2;
	
	Counter Counter0(
		.cin(Cin),
		.clock(Clk),
		.sclr(Rst_n),
		.cout(Cout0),
		.q(q0)
	);
	
	Counter Counter1(
		.cin(Cout0),
		.clock(Clk),
		.sclr(Rst_n),
		.cout(Cout1),
		.q(q1)
	);
	
	Counter Counter2(
		.cin(Cout1),
		.clock(Clk),
		.sclr(Rst_n),
		.cout(Cout2),
		.q(q2)
	);
	
	assign Cout = Cout2;

	assign q = {q2,q1,q0};

endmodule

测试激励文件:

`timescale 1ns/1ns
`define clock_period 20

module Counter_ip_top_tb;
	
	reg Clk;
	reg Rst_n;
	reg Cin;
	
	wire Cout;
	wire [11:0]q;
	
	Counter_ip_top ounter_ip_top(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.Cin(Cin),
		.Cout(Cout),
		.q(q)
	);
	
	initial Clk = 1;
	always#(`clock_period) Clk = ~Clk;
	
	initial begin
		Rst_n = 0;
		Cin = 1'b0;
		#(`clock_period*10)
		
		Rst_n = 1;
		#(`clock_period*5)
		
		Cin = 1'b1;
		#(`clock_period*5000)
	
		$stop;
	
	end

endmodule

运行仿真,看到的结果如下:
仿真结果1
Coutq没有任何变化,说明刚才由ip核生成的计数器的同步复位信号是高电平触发,即高电平触发系统复位

在一般的系统设计中,我们习惯于低电平触发系统复位,我们在顶层模块中稍加修改:

//使系统复位信号翻转以匹配ip核Counter的复位
wire Rst_n0;
assign Rst_n0 = ~Rst_n;

即:

module Counter_ip_top(
	input 			Clk,
	input 			Rst_n,
	input 			Cin,
	output 			Cout,
	output [11:0]	q
);

	wire Cout0;
	wire Cout1;
	wire Cout2;
	
	wire [3:0]q0;
	wire [3:0]q1;
	wire [3:0]q2;
	
	wire Rst_n0;
	assign Rst_n0 = ~Rst_n;
	
	Counter Counter0(
		.cin(Cin),
		.clock(Clk),
		.sclr(Rst_n0),
		.cout(Cout0),
		.q(q0)
	);
	
	Counter Counter1(
		.cin(Cout0),
		.clock(Clk),
		.sclr(Rst_n0),
		.cout(Cout1),
		.q(q1)
	);
	
	Counter Counter2(
		.cin(Cout1),
		.clock(Clk),
		.sclr(Rst_n0),
		.cout(Cout2),
		.q(q2)
	);
	
	assign Cout = Cout2;

	assign q = {q2,q1,q0};

endmodule

仿真结果符合设计预期:

仿真结果2

RTL视图:

RTL

csdn

🧸结尾


  • ❤️ 感谢您的支持和鼓励! 😊🙏
  • 📜您可能感兴趣的内容:
  • 【stm32开发】stm32+oled最小系统板资料(原理图、PCB、示例代码)【六一】
  • 【FPGA零基础学习之旅#5】产生非等占空比信号
  • 【Arduino TinyGo】【最新】使用Go语言编写Arduino-环境搭建和点亮LED灯
  • 【全网首发开源教程】【Labview机器人仿真与控制】Labview与Solidworks多路支配关系-四足爬行机器人仿真与控制
    遇见未来

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Virtual Serial Port Driver Pro 11 Crack

Virtual Serial Port Driver 虚拟串行端口驱动程序允许创建大量的虚拟COM端口&#xff0c;并为您提供充分模拟串行端口行为的巨大可能性。虚拟串行端口软件不仅仅是一个简单的COM端口模拟器。它提供了灵活的端口创建、管理和删除&#xff0c;允许测试串行软件&#xff0c;支持控…

Megatron + zero

文章目录 简介3D并行前置知识点&#xff1a;通信算子1. DP 数据并行显存效率优化&#xff08;ZeRO &#xff09;计算效率优化&#xff08;梯度累计减少通信&#xff09; 2. TP tensor并行&#xff08;算子内&#xff09;前置知识点&#xff1a;矩阵分块并行计算MLPself-attenti…

绿色荧光试剂210236-90-1,FITC Tyramide,Fluorescein-Tyramide

●中文名&#xff1a;荧光素酪胺 ●英文名&#xff1a;FITC Tyramide&#xff0c;Fluorescein-Tyramide&#xff0c;FITC TSA &#xff08;文章编辑资料汇总来源于&#xff1a;陕西新研博美生物科技有限公司小编MISSwu&#xff09;​ ●外观以及性质&#xff1a; 荧光素酪胺…

Vue核心

目录 一、初始Vue二、模板语法三、数据绑定四、el和data的两种写法五、MVVM模型六、数据代理七、事件处理八、计算属性九、监视属性十、绑定样式十一、条件渲染十二、列表渲染十三、收集表单数据十四、过滤器十五、内置指令十六、自定义指令十七、生命周期 简介&#xff1a; Vu…

【大数据之路2】分布式文件系统 HDFS

2. 分布式文件系统 HDFS 1. 引入HDFS【面试点】2. HDFS 概述1. HDFS 设计思路2. HDFS 架构3. HDFS 优缺点 3. HDFS 操作HDFS 读写基准测试 1. HDFS Shell 操作【重点】2. HDFS API 操作1. 访问数据1. 获取 FileSystem2. 文件的遍历3. 创建文件夹4. 文件的上传5. 文件的下载 2. …

实验篇(7.2) 07. 通过安全隧道访问指定网站 (FortiClient-SSL) ❀ 远程访问

【简介】通过前面的实验&#xff0c;我们已经了解了SSL VPN的隧道模式。FortiClient客户端拨号后&#xff0c;访问服务器IP的流量&#xff0c;会通过安全隧道到达远端防火墙&#xff0c;并访问DMZ接口下的服务器。那如果我想让更多的访问走安全隧道&#xff0c;但是又不确定是哪…

win11 安装tesseract-ocr

1. OCR OCR&#xff0c;即Optical Character Recognition&#xff0c;光学字符识别&#xff0c;是指通过扫描字符&#xff0c;然后通过其形状将其翻译成电子文本的过程。对于图形验证码来说&#xff0c;它们都是一些不规则的字符&#xff0c;这些字符确实是由字符稍加扭曲变换…

【P52 】JMeter 汇总图(Aggregate Graph)

文章目录 一、汇总图&#xff08;Aggregate Graph&#xff09;参数说明二、准备工作三、测试计划设计 一、汇总图&#xff08;Aggregate Graph&#xff09;参数说明 可以以图形的方式查看事务或者取样器的汇总报告 使用场景&#xff1a;用于评估测试结果 使用频率&#xff1…

Linux——安装Xshell7并使用vim操作文件(vim常用操作+快捷键+踩坑总结)

一、安装Xshell7完成远程登录 由于在安装Xshell6的时候很容易会出现&#xff0c;要求更新&#xff0c;但同时又显示已经是最新的版本的问题。当然出现这个问题的解决方法有很多&#xff0c;但最简单的方法就是直接使用Xshell7版本。实际测试后发现可以正常使用。&#xff08;关…

6个令大喵惊喜的 Python 库

6个令大喵惊喜的 Python 库 在过去的两年里&#xff0c;我一直在广泛使用Python。因此&#xff0c;我一直在寻找令人惊叹的库&#xff0c;可以增强我在数据工程和商业智能项目中的工作。 1.Pendulum Python 中有许多库可用于日期时间&#xff0c;但我发现 Pendulum 在日期的任何…

ChatGPT 使用 拓展资料:吴恩达大咖 Building Systems with the ChatGPT API 链式提示

ChatGPT 使用 拓展资料:吴恩达大咖 Building Systems with the ChatGPT API 链式提示 在本视频中,我们将学习如何通过将多个提示链接在一起,将复杂的任务拆分为一系列更简单的子任务。你可能会想,为什么要将一个任务拆分为多个提示,而你可以像我们在上一个视频中学到的那样…

高级IO -- 多路转接之 select

高级IO – 多路转接之 select 文章目录 高级IO -- 多路转接之 select初识selectselect 函数原型关于fd_set结构 select使用示例编写Sock编写selectService测试 理解select执行过程socket就绪条件读就绪写就绪 select的特点select的缺点select的缺点 初识select 系统提供select…

2023同为测试你的薪资为何比别人低?

软件测试这个行业我见过工作5年依然是初级水平的功能测试&#xff0c;拿着不到1W的薪资&#xff0c;也见过1年时间达到高级自动化水平的大牛&#xff01;拿着20K的薪资。 影响你薪资的有两点&#xff01; 一、你的技术水平高低直接决定你薪资的多少&#xff0c;工作时间长短并…

3D引擎和渲染

常见的三维引擎 三维引擎按平台可分为客户端三维引擎&#xff0c;Web端三维引擎&#xff1b;按用途可分为游戏三维引擎、CAD/CAM/CAE三维引擎&#xff1b; 游戏引擎常见的有UE4、Unity3D&#xff1b;CAD工程用的三维引擎又分商用的还有开源的&#xff0c;商用的比较著名的有A…

华为OD-2023B卷-太阳能板最大面积(java)

2.华为OD-2023B卷 -太阳能板最大面积(回到目录) 太阳能板最大面积 知识点分治 时间限制:1s 空间限制:32MB 限定语言:不限 难度:★★ 中规中矩的双指针题目。暴力for循环过不了全部样例。 题目描述: 给航天器一侧加装长方形或正方形的太阳能板(图中的红色斜线区域),需…

uniapp请求封装入门级实战记录

简单记录一下uniapp请求进行封装的相关内容,方便以后查看! 1.目录结构 2.封装文件 2.1 全局公共方法封装 2.2 请求方法封装 2.3 项目请求路径封装 2.4 常用变量封装 2.5 页面使用 1.目录结构 项目根目录下创建common文件夹,包含内容: …

springBoot源码分析如何加载配置文件

前言&#xff1a;springBoot的版本是 2.2.4.RELEASE 一、入口 /*** Run the Spring application, creating and refreshing a new* {link ApplicationContext}.* param args the application arguments (usually passed from a Java main method)* return a running {link A…

DM5加密

MD5加密 概述 MD5&#xff08;Message Digest Algorithm 5&#xff09;是一种常用的哈希函数&#xff0c;能够将任意长度的消息压缩成一个128位的哈希值。它由Ronald Rivest在1991年设计&#xff0c;其设计目标是用来取代较早的MD4算法。 MD5算法通过多次处理分组数据来生成…

2023年5月青少年机器人技术等级考试理论综合试卷(三级)

青少年机器人技术等级考试理论综合试卷&#xff08;三级&#xff09;2023.06 分数&#xff1a; 100 题数&#xff1a; 30 一、 单选题(共 20 题&#xff0c; 共 80 分) 1.如图所示电路&#xff0c; 下列说法正确的是&#xff1f; &#xff08; &#xff09; A.电路中电阻 R3 和…

Kafka有几种消费者分区分配策略?

Range范围分配策略 Range范围分配策略是Kafka默认的分配策略&#xff0c;它可以确保每个消费者消费的分区数量是均衡的。 注意&#xff1a;Rangle范围分配策略是针对每个Topic的。 配置 配置消费者的partition.assignment.strategy为org.apache.kafka.clients.consumer.Ran…