从零开始设计RISC-V处理器——五级流水线之数据通路的设计

news2024/12/23 9:01:18

系列文章目录

(一)从零开始设计RISC-V处理器——指令系统
(二)从零开始设计RISC-V处理器——单周期处理器的设计
(三)从零开始设计RISC-V处理器——单周期处理器的仿真
(四)从零开始设计RISC-V处理器——ALU的优化
(五)从零开始设计RISC-V处理器——五级流水线之数据通路的设计
(六)从零开始设计RISC-V处理器——五级流水线之控制器的设计
(七)从零开始设计RISC-V处理器——五级流水线之数据冒险
(八)从零开始设计RISC-V处理器——五级流水线之控制冒险
(九)从零开始设计RISC-V处理器——五级流水线之分支计算前移
(十)从零开始设计RISC-V处理器——五级流水线之静态预测


文章目录

  • 系列文章目录
  • 前言
  • 一、数据通路的划分
  • 二、流水线设计
    • 1.取指阶段(IF_stage)
    • 2.IF_ID流水线寄存器
    • 3.译码阶段(ID_stage)
    • 4.ID_EX流水线寄存器
    • 5.执行阶段(EX_stage)
    • 6.EX_MEM流水线寄存器
    • 7.访存阶段(MEM_stage)
    • 8.MEM_WB流水线寄存器
    • 9.写回阶段(WB_stage)
  • 三、数据通路顶层模块
  • 总结


前言

前面几篇文章已经描述了设计一个单周期的CPU的完整过程以及代码。从这篇文章开始,我们逐步对这个CPU进行优化。今天首先进行五级流水线的数据通路的设计。


一、数据通路的划分

回顾以下单周期的处理器的数据通路图:
在这里插入图片描述
所谓单周期处理器,就是指处理器执行每一条指令都在一个时钟周期内完成。由于不同指令的数据通路不同,执行不同的指令做需要的时间也不同,单周期处理器必须保证所花时间最长的那一条指令能够在一个时钟周期内执行完毕。因此这就限制了时钟周期的大小。
流水线的思想,就是将一个很大的组合逻辑拆分成几个比较小的组合逻辑,使得这几个小的模块能够并行执行,通过增加数据吞吐量来提升执行效率。
在这里我们将处理器执行一条指令的过程拆分为取指,译码,执行,访存,写回五个阶段。
在这里插入图片描述

这相当于将一个很大的组合逻辑拆分成五个比较小的组合逻辑,只需要保证每个小模块能够在一个时钟周期内执行完毕。因此可以一定程度上缩小CPU时钟周期,即提升CPU的频率。
既然要进行拆分,就不是简单的将几个模块进行重组打包,而是要彻底的打断各个子模块之间的“路径”,同时各个子模块之间原有的信号流通不能改变。
所以需要在两个子模块之间添加一组流水线寄存器。
其作用有二:
(1)用寄存器打断组合逻辑
(2)进行信号在两个子模块之间的传递
其信号传递关系如下:
在这里插入图片描述

综上所述,进行五级流水线的数据通路的设计,首先需要进行模块的划分,然后在每两个模块之间添加流水线寄存器。下面进行详细描述。

二、流水线设计

1.取指阶段(IF_stage)

取指阶段的功能是产生新的pc值,并读取指令存储器。因此取指阶段包括pc_reg和instr_memory两个子模块。此处 instr_memory为一个存储器,将其当作CPU外部的部件而不将其写入if_stage阶段。

代码如下:

module if_stage(
	input clk,
	input rst_n,
	input [31:0]pc_if_i,
	output [31:0]pc_if_o,
	output [7:0]rom_addr

    );

	pc_reg pc_reg_inst (
    .clk(clk), 
    .rst_n(rst_n), 
    .pc_new(pc_if_i), 
    .pc_out(pc_if_o)
    );
	
	assign rom_addr=pc_if_o[9:2];

endmodule


2.IF_ID流水线寄存器

此模块传递两个信号,分别是pc和读出的32位的指令。
pc为什么向后传递?因为在执行阶段计算下一个pc的值以及跳转指令的目标地址时,都需要用到当前模块的pc,所以pc需要逐级传递,保证pc与所在阶段执行的指令是一一对应的。

代码如下:

`include "define.v"

module if_id_regs(
	input clk,
	input rst_n,
	input [31:0]pc_if_id_i,
	input [31:0]instr_if_id_i,
	output reg [31:0]pc_if_id_o,
	output reg [31:0]instr_if_id_o
    );

	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			pc_if_id_o<=`zeroword;
		else
			pc_if_id_o<=pc_if_id_i;
	end
	
	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			instr_if_id_o<=`zeroword;
		else
			instr_if_id_o<=instr_if_id_i;
	end

endmodule


3.译码阶段(ID_stage)

译码阶段的功能是将上一级传递的32位指令进行译码并且读取寄存器堆。
所以此模块包含instr_decode和registers两个子模块。

代码如下:

module id_stage(
	input clk,
	input rst_n,
	input RegWrite_id_i,
	input [31:0]Wr_reg_data_id_i,
	input [31:0] instr_id_i,
	output [6:0] opcode_id_o,
	output [2:0] func3_id_o,
	output func7_id_o,
	output [31:0] imme_id_o,
	output [31:0] Rd_data1_id_o,
	output [31:0] Rd_data2_id_o

    );

	wire [4:0]Rs1;
	wire [4:0]Rs2;
	wire [4:0]Rd;
	
	
	instr_decode instr_decode_inst (
    .instr(instr_id_i), 
    .opcode(opcode_id_o), 
    .func3(func3_id_o), 
    .func7(func7_id_o), 
    .Rs1(Rs1), 
    .Rs2(Rs2), 
    .Rd(Rd), 
    .imme(imme_id_o)
    );
	
    registers registers_inst (
    .clk(clk), 
	.rst_n(rst_n), 
    .W_en(RegWrite_id_i), 
    .Rs1(Rs1), 
    .Rs2(Rs2), 
    .Rd(Rd), 
    .Wr_data(Wr_reg_data_id_i), 
    .Rd_data1(Rd_data1_id_o), 
    .Rd_data2(Rd_data2_id_o)
    );
endmodule


4.ID_EX流水线寄存器

此模块传递四个信号,pc,imme,Rd_data1,Rd_data2。

代码如下:

`include "define.v"
module id_ex_regs(
	input clk,
	input rst_n,
	input [31:0]pc_id_ex_i,
	input [31:0]imme_id_ex_i,
	input [31:0]Rd_data1_id_ex_i,
	input [31:0]Rd_data2_id_ex_i,
	output reg [31:0]pc_id_ex_o,
	output reg [31:0]imme_id_ex_o,
	output reg [31:0]Rd_data1_id_ex_o,
	output reg [31:0]Rd_data2_id_ex_o,
    );

always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			pc_id_ex_o<=`zeroword;
		else
			pc_id_ex_o<=pc_id_ex_i;
	end
	
always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			imme_id_ex_o<=`zeroword;
		else
			imme_id_ex_o<=imme_id_ex_i;
	end
	
always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			Rd_data1_id_ex_o<=`zeroword;
		else
			Rd_data1_id_ex_o<=Rd_data1_id_ex_i;
	end

always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			Rd_data2_id_ex_o<=`zeroword;
		else
			Rd_data2_id_ex_o<=Rd_data2_id_ex_i;
	end
	
	
	
	

endmodule


5.执行阶段(EX_stage)

执行阶段的功能是执行ALU的计算并且计算新的pc的值。
所以包含alu模块,分支判断模块,两个加法器(pc+4,pc+imme),三个选择器(alu数据来源选择,pc顺序执行与pc跳转选择,jalr选择)。

代码如下:

module ex_stage(
	input ALUctl_ex_i,
	input beq_ex_i,
	input bne_ex_i,
	input blt_ex_i,
	input bge_ex_i,
	input bltu_ex_i,
	input bgeu_ex_i,
	input jal_ex_i,
	input jalr_ex_i,
	input ALUSrc_ex_i,
	input [31:0]pc_ex_i,
	input [31:0]imme_ex_i,
	input [31:0]Rd_data1_ex_i,
	input [31:0]Rd_data2_ex_i,
	output [31:0]ALU_result_ex_o,
	output [31:0]pc_new_ex_o,
	output [31:0]pc_jump_o,
	output [31:0]Rd_data2_ex_o,
	output [31:0]imme_ex_o,
	output [31:0]pc_order_ex_o
    );

	wire [31:0]ALU_DB;
	wire zero;
	wire ALU_result_sig;
	wire jump_flag;
	wire [31:0]pc_order;
	wire [31:0]pc_jump_order;
	wire pc_jalr;
	
	
	assign pc_jalr={ALU_result[31:1],1'b0};
	assign ALU_result_sig=ALU_result[31];
	assign imme_ex_o=imme_ex_i;
	assign pc_order_ex_o=pc_order;
	
	alu alu_inst (
    .ALU_DA(Rd_data1_ex_i), 
    .ALU_DB(ALU_DB), 
    .ALU_CTL(ALUctl_ex_i), 
    .ALU_ZERO(zero), 
    .ALU_OverFlow(), 
    .ALU_DC(ALU_result_ex_o)
    );

	branch_judge branch_judge_inst (
    .beq(beq_ex_i,), 
    .bne(bne_ex_i,), 
    .blt(blt_ex_i,), 
    .bge(bge_ex_i,), 
    .bltu(bltu_ex_i,), 
    .bgeu(bgeu_ex_i,), 
    .jal(jal_ex_i,), 
    .jalr(jalr_ex_i,), 
    .zero(zero), 
    .ALU_result_sig(ALU_result_sig), 
    .jump_flag(jump_flag)
    );

///pc+4	
	cla_adder32 pc_adder_4 (
    .A(pc_ex_i), 
    .B(32'd4), 
    .cin(1'd0), 
    .result(pc_order), 
    .cout()
    );
	
///pc+imme
	cla_adder32 pc_adder_imme (
    .A(pc_ex_i), 
    .B(imme_ex_i), 
    .cin(1'd0), 
    .result(pc_jump_o), 
    .cout()
    );

///pc_sel
	mux pc_mux (
    .data1(pc_jump_o), 
    .data2(pc_order), 
    .sel(jump_flag), 
    .dout(pc_jump_order)
    );
///pc_jalr
	mux pc_jalr_mux (
    .data1(pc_jalr), 
    .data2(pc_jump_order), 
    .sel(jalr_ex_i), 
    .dout(pc_new_ex_o)
    );

///ALUdata_sel	
	mux ALU_data_mux (
    .data1(imme_ex_i), 
    .data2(Rd_data2_ex_i), 
    .sel(ALUSrc_ex_i), 
    .dout(ALU_DB)
    );
	
	
	
endmodule


6.EX_MEM流水线寄存器

此模块传递ALU_result,pc_jump,Rd_data2,imme,pc_order五个模块。
ALU_result将在访存阶段作为访存的地址使用,在写回阶段作为运算结果写回寄存器。
pc_jump,pc_order在写回阶段写回寄存器。
Rd_data2在访存阶段作为写入存储器的数据使用。
imme在写回阶段使用。

代码如下:

`include "define.v"
module ex_mem_regs(
	input clk,
	input rst_n,
	input [31:0]ALU_result_ex_mem_i,
	input [31:0]pc_jump_ex_mem_i,
	input [31:0]Rd_data2_ex_mem_i,
	input [31:0]imme_ex_mem_i,
	input [31:0]pc_order_ex_mem_i,
	output [31:0]ALU_result_ex_mem_o,   
	output [31:0]pc_jump_ex_mem_o,
	output [31:0]Rd_data2_ex_mem_o,     //DM
	output [31:0]imme_ex_mem_o,
	output [31:0]pc_order_ex_mem_o,
    );

	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			ALU_result_ex_mem_o<=`zeroword;
		else
			ALU_result_ex_mem_o<=ALU_result_ex_mem_i;
	end
	
	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			pc_jump_ex_mem_o<=`zeroword;
		else
			pc_jump_ex_mem_o<=pc_jump_ex_mem_i;
	end
	
	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			Rd_data2_ex_mem_o<=`zeroword;
		else
			Rd_data2_ex_mem_o<=Rd_data2_ex_mem_i;
	end
	
	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			imme_ex_mem_o<=`zeroword;
		else
			imme_ex_mem_o<=imme_ex_mem_i;
	end
	
	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			pc_order_ex_mem_o<=`zeroword;
		else
			pc_order_ex_mem_o<=pc_order_ex_mem_i;
	end
	
	

endmodule


7.访存阶段(MEM_stage)

访存阶段与取指阶段类似,都是访问外部存储器,在这里将存储器与CPU进行分开,所以此阶段只需要输出地址与数据给数据存储器,并且接收数据存储器读出的数据,此部分代码在CPU的顶层模块体现。

8.MEM_WB流水线寄存器

此模块传递5个信号,均在写回阶段使用。loaddata为访存阶段新产生的数据,来自于读数据存储器。

代码如下:

`include "define.v"
module mem_wb_regs(
	input [31:0]ALU_result_mem_wb_i,   
	input [31:0]pc_jump_mem_wb_i,
	input [31:0]loaddata_mem_wb_i,     //DM
	input [31:0]imme_mem_wb_i,
	input [31:0]pc_order_mem_wb_i,
	output reg [31:0]ALU_result_mem_wb_o,   
	output reg [31:0]pc_jump_mem_wb_o,
	output reg [31:0]loaddata_mem_wb_o,     //DM
	output reg [31:0]imme_mem_wb_o,
	output reg [31:0]pc_order_mem_wb_o,
    );
	
	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			ALU_result_mem_wb_o<=`zeroword;
		else
			ALU_result_mem_wb_o<=ALU_result_mem_wb_i;
	end
	
	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			pc_jump_mem_wb_o<=`zeroword;
		else
			pc_jump_mem_wb_o<=pc_jump_mem_wb_i;
	end
	
	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			loaddata_mem_wb_o<=`zeroword;
		else
			loaddata_mem_wb_o<=loaddata_mem_wb_i;
	end
	
	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			imme_mem_wb_o<=`zeroword;
		else
			imme_mem_wb_o<=imme_mem_wb_i;
	end
	
	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			pc_order_mem_wb_o<=`zeroword;
		else
			pc_order_mem_wb_o<pc_order_mem_wb_i;
	end

endmodule


9.写回阶段(WB_stage)

写回阶段包括4个选择器,最终输出一个数据写回寄存器堆。

代码如下:


module wb_stage(
	input MemtoReg,
	input jal,
	input jalr,
	input lui,
	input U_type,
	input [31:0]ALU_result_wb_i,   
	input [31:0]pc_jump_wb_i,
	input [31:0]loaddata_wb_i,    
	input [31:0]imme_wb_i,
	input [31:0]pc_order_wb_i,
	output [31:0]Wr_reg_data_wb_o

    );
	
	wire [31:0]WB_data;
	wire reg_sel;
	wire [31:0]Wr_reg_data1;
	wire [31:0]Wr_reg_data2;
	
	assign reg_sel=jal | jalr ;
	
	/ALU_result or datamem	
	mux wb_data_mux (
    .data1(loaddata_wb_i), 
    .data2(ALU_result_wb_i), 
    .sel(MemtoReg), 
    .dout(WB_data)
    );
	
	
Wr_data_sel
	mux jalr_mux (
    .data1(pc_order_wb_i), 
    .data2(WB_data), 
    .sel(reg_sel), 
    .dout(Wr_reg_data2)
    );
	
	mux lui_mux (
    .data1(imme_wb_i), 
    .data2(pc_jump_wb_i), 
    .sel(lui), 
    .dout(Wr_reg_data1)
    );
	
	mux wr_reg_mux (
    .data1(Wr_reg_data1), 
    .data2(Wr_reg_data2), 
    .sel(U_type), 
    .dout(Wr_reg_data_wb_o)
    );
	
	
	
	

endmodule


三、数据通路顶层模块

将以上五个子模块以及四个流水线寄存器组进行实例化,将模块与模块之间的信号进行连接,即得到数据通路部分。

代码如下:

module datapath(
	input 	clk,
	input   rst_n,
	input   [31:0]instr,


	input   MemtoReg,
	input   ALUSrc,
	input   RegWrite,
	input   lui,
	input   U_type,
	input   jal,
	input   jalr,
	input   beq,
	input   bne,
	input   blt,
	input   bge,
	input   bltu,
	input   bgeu,
	input   [3:0]ALUctl,
	
	input [31:0]loaddata,
	output  [7:0]rom_addr,
	output [31:0]Wr_mem_data,
	output [31:0]ALU_result,
	output [6:0]opcode,
	output [2:0]func3,
	output func7
	
);

	wire [31:0]pc_if_i;
	wire [31:0]pc_if_o;

	wire [31:0]pc_if_id_o;
	wire [31:0]instr_if_id_o;

	
	wire [31:0]imme_id_o;
	wire [31:0]Rd_data1_id_o;
	wire [31:0]Rd_data2_id_o;
	
	wire [31:0]pc_id_ex_o;
	wire [31:0]imme_id_ex_o;
	wire [31:0]Rd_data1_id_ex_o;
	wire [31:0]Rd_data2_id_ex_o;
	
	wire [31:0] ALU_result_ex_o;
	wire [31:0] pc_jump_o;
	wire [31:0] Rd_data2_ex_o;
	wire [31:0] imme_ex_o;
	wire [31:0] pc_order_ex_o;
	
	
	wire [31:0] ALU_result_ex_mem_o;
	wire [31:0] pc_jump_ex_mem_o;
	wire [31:0] Rd_data2_ex_mem_o;
	wire [31:0] imme_ex_mem_o;
	wire [31:0] pc_order_mem_wb_o;
	
	
	wire [31:0] ALU_result_mem_wb_o;
	wire [31:0] pc_jump_mem_wb_o;
	wire [31:0] loaddata_mem_wb_o;
	wire [31:0] imme_mem_wb_o;
	wire [31:0] pc_order_mem_wb_o;

	
	wire [31:0]Wr_reg_data_wb_o;
	
	
	
	
if_stage if_stage_inst (
    .clk(clk), 
    .rst_n(rst_n), 
    .pc_if_i(pc_if_i), 
    .pc_if_o(pc_if_o), 
    .rom_addr(rom_addr)
    );

if_id_regs  if_id_regs_inst(
    .clk(clk), 
    .rst_n(rst_n), 
    .pc_if_id_i(pc_if_o), 
    .instr_if_id_i(instr), 
    .pc_if_id_o(pc_if_id_o), 
    .instr_if_id_o(instr_if_id_o)
    );

id_stage id_stage_inst (
    .clk(clk), 
    .rst_n(rst_n), 
    .RegWrite_id_i(), 
    .Wr_reg_data_id_i(Wr_reg_data_wb_o), 
    .instr_id_i(instr_if_id_o), 
    .opcode_id_o(opcode), 
    .func3_id_o(func3), 
    .func7_id_o(func7), 
    .imme_id_o(imme_id_o), 
    .Rd_data1_id_o(Rd_data1_id_o), 
    .Rd_data2_id_o(Rd_data2_id_o)
    );

id_ex_regs id_ex_regs_inst (
    .clk(clk), 
    .rst_n(rst_n), 
    .pc_id_ex_i(pc_if_id_o), 
    .imme_id_ex_i(imme_id_o), 
    .Rd_data1_id_ex_i(Rd_data1_id_o), 
    .Rd_data2_id_ex_i(Rd_data2_id_o), 
    .pc_id_ex_o(pc_id_ex_o), 
    .imme_id_ex_o(imme_id_ex_o), 
    .Rd_data1_id_ex_o(Rd_data1_id_ex_o), 
    .Rd_data2_id_ex_o(Rd_data2_id_ex_o)
    );

ex_stage ex_stage_inst (
    .ALUctl_ex_i(), 
    .beq_ex_i(), 
    .bne_ex_i(), 
    .blt_ex_i(), 
    .bge_ex_i(), 
    .bltu_ex_i(), 
    .bgeu_ex_i(), 
    .jal_ex_i(), 
    .jalr_ex_i(), 
    .ALUSrc_ex_i(), 
    .pc_ex_i(), 
    .imme_ex_i(), 
    .Rd_data1_ex_i(Rd_data1_id_ex_o), 
    .Rd_data2_ex_i(Rd_data2_id_ex_o), 
    .ALU_result_ex_o(ALU_result_ex_o), 
    .pc_new_ex_o(pc_if_i), 
    .pc_jump_o(pc_jump_o), 
    .Rd_data2_ex_o(Rd_data2_ex_o), 
    .imme_ex_o(imme_ex_o), 
    .pc_order_ex_o(pc_order_ex_o)
    );
	
ex_mem_regs ex_mem_regs_inst (
    .clk(clk), 
    .rst_n(rst_n), 
    .ALU_result_ex_mem_i(ALU_result_ex_o), 
    .pc_jump_ex_mem_i(pc_jump_o), 
    .Rd_data2_ex_mem_i(Rd_data2_ex_o), 
    .imme_ex_mem_i(imme_ex_o), 
    .pc_order_ex_mem_i(pc_order_ex_o), 
    .ALU_result_ex_mem_o(ALU_result_ex_mem_o), 
    .pc_jump_ex_mem_o(pc_jump_ex_mem_o), 
    .Rd_data2_ex_mem_o(Rd_data2_ex_mem_o), 
    .imme_ex_mem_o(imme_ex_mem_o), 
    .pc_order_ex_mem_o(pc_order_ex_mem_o)
    );

mem_wb_regs mem_wb_regs_inst (
    .ALU_result_mem_wb_i(ALU_result_ex_mem_o), 
    .pc_jump_mem_wb_i(pc_jump_ex_mem_o), 
    .loaddata_mem_wb_i(loaddata), 
    .imme_mem_wb_i(imme_ex_mem_o), 
    .pc_order_mem_wb_i(pc_order_ex_mem_o), 
    .ALU_result_mem_wb_o(ALU_result_mem_wb_o), 
    .pc_jump_mem_wb_o(pc_jump_mem_wb_o), 
    .loaddata_mem_wb_o(loaddata_mem_wb_o), 
    .imme_mem_wb_o(imme_mem_wb_o), 
    .pc_order_mem_wb_o(pc_order_mem_wb_o)
    );
	
wb_stage wb_stage_inst (
    .MemtoReg(), 
    .jal(), 
    .jalr(), 
    .lui(), 
    .U_type(), 
    .ALU_result_wb_i(ALU_result_mem_wb_o), 
    .pc_jump_wb_i(pc_jump_mem_wb_o), 
    .loaddata_wb_i(loaddata_mem_wb_o), 
    .imme_wb_i(imme_mem_wb_o), 
    .pc_order_wb_i(pc_order_mem_wb_o), 
    .Wr_reg_data_wb_o(Wr_reg_data_wb_o)
    );
	
endmodule

总结

以上就是五级流水线处理器的数据通路部分的设计思路,总结下来就是,将CPU执行指令的逻辑分为五个部分,中间添加流水线寄存器组,一方面打断组合逻辑以提升CPU的时钟频率,另一方面保证信号在各级之间流通。
本篇文章仅仅介绍了数据通路部分,可以看到在数据通路的代码中,一些控制信号还是空的,因此下一篇文章将对控制器进行流水线的设计。

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

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

相关文章

五十、Spring

1.Spring概述 1.1 Spring是什么 Spring是分层的 Java SE/EE应用 full-stack(全栈式) 轻量级开源框架。 提供了表现层 SpringMVC和持久层 Spring JDBC Template以及 业务层 事务管理等众多的企业级应用 技术&#xff0c;还能整合开源世界众多著名的第三方框架和类库&#xf…

javascript中使用class和prototype的区别

javascript中使用class和prototype的区别 本文将介绍在 JavaScript 何时使用class以及何时使用prototype。 prototype 首先先介绍一下prototype的概念&#xff0c;在Javascript中&#xff0c;所有的对象都从原型中继承属性和方法。 function Car(brand, vinNumber) {this.b…

实现 Rollup 插件alias 并使用vitest提高开发效率

本篇文章是对 实现 Rollup 插件 alias | 使用 TypeScript 实现库的基本流程 | 使用单元测试提高开发效率 的总结。其中涉及到开发一个组件库的诸多知识点。 实现一个经常用的 rollup 插件 alias 首先执行npm init命令初始化一个package.json文件&#xff0c;因为插件使用了ty…

【大模型】ChatGLM2-6B 快速使用

教程 Bilibili&#xff1a;清华开源ChatGLM2-6B安装使用 手把手教程&#xff0c;轻松掌握 代码&#xff1a;https://github.com/THUDM/ChatGLM2-6B 模型&#xff1a;https://huggingface.co/THUDM/chatglm2-6b、https://cloud.tsinghua.edu.cn/d/674208019e314311ab5c/?p%2Fc…

【Java从入门到大牛】面向对象进阶下篇

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;Java从入门到大牛 &#x1f320; 首发时间&#xff1a;2023年7月19日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43…

vue3后台管理系统封装的普通搜索框组件

1.普通搜索框效果 代码&#xff1a;SearchItem.vue <template><div class"searchBox" id"searchBox"><!-- <a-form ref"formRef" name"advanced_search" class"ant-advanced-search-form" :model"f…

【笔记MD】

https://editor.csdn.net/md/?not_checkout1&articleId131798584 这里写自定义目录标题 https://editor.csdn.net/md/?not_checkout1&articleId131798584欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入…

基于PaddleOCR与OpenVINO™的结构化输出Pipeline

飞桨&#xff08;PaddlePaddle&#xff09;是百度自主研发的中国首个开源开放、功能丰富的产业级深度学习平台&#xff0c;以百度多年的深度学习技术研究和业务应用为基础。飞桨深度学习平台集核心框架、基础模型库、端到端开发套件、丰富的工具组件于一体&#xff0c;还包括了…

QGIS绘制一张地图——创建和编辑绘制线要素、由线要素生成面要素、面要素的编辑

前言 我们以描绘北京市市区案例来演示这部分功能。步骤大致如下: 1、按照市区分区的分界线来绘制线要素。 2、根据所绘线要素生成面要素。 3、对生成的面要素做整理编辑。待绘制底图如图所示: 一、创建和编辑绘制线要素 1.1 创建线要素 我们点击新建Shapefile要素按钮,…

ES6——Iterator 和 for...of 循环

Iterator:遍历器 是一接口&#xff0c;为不同的数据结构提供统一的访问机制&#xff0c;只要当前数据结构部署了iterator接口&#xff0c;当前数据结构就可以遍历。 作用&#xff1a;1、为不同的数据结构&#xff0c;提供统一的访问机制 2、使当前数据结构的成员依次被访问 3…

园区数字经济腾飞,先要长出“网络双翼”

没有人会否认&#xff0c;过去四十多年来&#xff0c;中国经济的腾飞&#xff0c;在全球发展史中写下了浓墨重彩的一笔。其中&#xff0c;产业园区有着不可替代的作用。有人说&#xff0c;园区的四十年&#xff0c;也是一部中国经济的演进史。 作为距离企业业务最近的网络层级&…

牛客网:华为机试刷题记录

牛客网&#xff1a;华为机试刷题记录 前言一、HJ15 求int型正整数在内存中存储时1的个数二、HJ10 字符个数统计三、HJ8 合并表记录四、HJ17 坐标移动五、HJ19 简单错误记录 前言 本文主要是想记录一下华为机试刷题过程中的总结 牛客网的华为机试链接&#xff1a;https://www.n…

通达信超级分时主图指标公式_通达信公式

{日引用} MA3:MA(C,3); MA5:MA(C,5); MA7:MA(C,7); MA10:MA(C,10); MA21:MA(C,21); {BBIYY} DKX:(MA(C,3)MA(C,6)MA(C,12)MA(C,24))/4; {LJFSYY} H1:REF(H,1); L1:REF(L,1); {大盘分时主图} SJ:IF(HOUR<12,(HOUR-9.5)*60MINUTE,(HOUR-11)*60MINUTE); F:DYNAINFO(3)…

J-Flash烧录工具如何添加新的芯片类型

0 Preface/Foreword 1 添加方法 1.1 修改JLinkDevices.xm <!-- --> <!-- CMS --> <!-- --> <Device> <ChipInfo Vendor"CMS32" Name"CMS32L051" Core"JLINK_CORE_CORTEX_…

2023年7月江苏/北京/深圳CDGA/CDGP数据治理认证招生

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

Claude API接口调用配置方法和脚本

直接通过API调用Claude方法&#xff0c;这个已经应用到一键成片AI绘画软件中。对于GPT来说速度慢了一点但是还能接受和GPT35差不多&#xff0c;最重要的是不花钱。 先来看我在项目中的应用把。 创建Slack工作台 slack注册网址&#xff0c;请使用谷歌邮箱&#xff0c;点击登…

自洽性改善语言模型中的思维链推理7.13、7.14

自洽性改善语言模型中的思维链推理 摘要介绍对多样化路径的自洽实验实验设置主要结果当CoT影响效率时候&#xff0c;SC会有所帮助与现有方法进行比较附加研究 相关工作总结 原文&#xff1a; 摘要 本篇论文提出了一种新的编码策略——自洽性&#xff0c;来替换思维链中使用的…

Vue3中的透传Attributes / $attrs:简化组件开发的利器

前言 Vue3推出了一系列新功能和改进。使用下来后&#xff0c;其中一个很实用的新特性就是透传 Attributes&#xff08;透传属性&#xff09;。本文将介绍 Vue3中的透传 Attributes&#xff0c;并提结合代码示例来展示它在实际项目中的使用。 一、什么是透传 Attributes&#x…

多网点多设备的动环机房都怎样集中管理的呢?

多机房动力环境集中监控系统针对分布不同区域、设备数量较多、减少人工巡检费用支出而设计的在线集中监控的系统平台。可用于分布式的UPS电源、精密空调、空气质量检测传感器、精密配电等设备的网络集中监控&#xff0c;通过TCP/IP网络&#xff0c;可以实时的跨地域的监控多台都…

四、DML-2.数据操作-修改

原数据表&#xff1a; 一、案例一 修改id为1的数据&#xff0c;将name修改为itheima update employee set name itheima where id 1; 步骤一&#xff1a;输入update命令并执行&#xff1a; 步骤二&#xff1a;刷新查看employee表修改后数据&#xff1a; 二、案例二 修改id为…