当前位置:网站首页>FPGA based analog I ² C protocol system design (with main code)
FPGA based analog I ² C protocol system design (with main code)
2022-06-27 15:27:00 【FPGA technology Jianghu】
Hello, great Xia , Welcome to FPGA Technical Jianghu , The world is so big , Meeting is fate .
Today, I bring you FPGA Of simulation I²C Protocol design , Because of the long space , It is divided into three parts . Today brings the third , The next part , Program simulation and testing . Don't talk much , Loading .
There are also related articles before , Here is a hyperlink , For your reference only .
Source series : be based on FPGA Of IIC Design ( Source attached works )
Here are also the hyperlinks to the first two articles :
be based on FPGA The simulation I²C Protocol design ( On )
be based on FPGA The simulation I²C Protocol design ( in )
Reading guide
I²C(Inter-Integrated Circuit), It's actually I²C Bus abbreviation , Chinese is integrated circuit bus , It's a serial communication bus , Using multi master slave architecture , By Philips in 1980 In order to make motherboard 、 Embedded systems or mobile phones are developed to connect low-speed peripheral devices .I²C The correct reading of is “I square C”("I-squared-C"), and “I Two C”("I-two-C") Is another wrong but widely used way of reading . since 2006 year 10 month 1 The date of , Use I²C The agreement no longer requires the payment of patent fees , But manufacturers still have to pay for I²C Slave device address .
I²C Simply speaking , Is a serial communication protocol ,I²C The communication protocol and communication interface are widely used in many projects , Such as serial in the field of data acquisition AD, Camera configuration in the field of image processing , In the field of industrial control X X-ray tube configuration, etc . besides , because I²C The agreement occupies IO There are very few resources , Easy to connect , Therefore, it is often used in engineering I²C The interface is used as the communication protocol between different chips .I²C A serial bus usually has two signal wires , One is a two-way data line SDA, The other is the clock line SCL. All received I²C Serial data on the bus device SDA All connected to the bus SDA On , Clock line of each device SCL Connected to the bus SCL On .
In modern electronic systems , There are numerous IC Need to communicate with each other and with the outside world . In order to simplify the circuit design ,Philips The company has developed an internal IC Simple bidirectional two-wire serial bus for control I²C(Intel-Integrated Circuit bus).1998 When launched in I²C bus protocol 2.0 version ,I²C The agreement has actually become an international standard .
It's going on FPGA When the design , It is often necessary to provide with the periphery I²C Interface chip communication . For example, low power consumption CMOS Real time clock / Calendar chip PCF8563、LCD Driver chip PCF8562、 Parallel port expansion chip PCF8574、 keyboard /LED Driver ZLG7290 And so on I²C Interface . So in FPGA Middle simulation I²C The interface has become FPGA Develop the necessary steps .
This article will explain in detail in FPGA The chip uses VHDL/Verilog HDL simulation I²C agreement , And compiling TestBench Methods of simulating and testing programs .
Part three content summary : This chapter will introduce the simulation and testing of the program , Including the simulation of the master node 、 Simulation of slave nodes 、 Simulation main program 、 Simulation results and summary .
Four 、 Program simulation and testing
I²C After the protocol simulation program is completed , It also needs to test the function of the program through the simulation program . The simulation of this program includes 3 Parts of : The first part is the simulation of the master node , Analog data reading / Write ; The second part is the simulation of slave nodes , Reception and response of analog data ; The third part is the main simulation program , Be responsible for the control of the whole simulation process .
4.1 Simulation of master node
The content of master node simulation includes reading data 、 Write data and compare data 3 part , The code is as follows :
`include "timescale.v"
// Module definition
module wb_master_model(clk, rst, adr, din, dout, cyc, stb, we, sel, ack, err, rty);
// Parameters
parameter dwidth = 32;
parameter awidth = 32;
// Input 、 Output
input clk, rst;
output [awidth -1:0] adr;
input [dwidth -1:0] din;
output [dwidth -1:0] dout;
output cyc, stb;
output we;
output [dwidth/8 -1:0] sel;
input ack, err, rty;
//WIRE Definition
reg [awidth -1:0] adr;
reg [dwidth -1:0] dout;
reg cyc, stb;
reg we;
reg [dwidth/8 -1:0] sel;
reg [dwidth -1:0] q;
// Storage logic
// initialization
initial
begin
adr = {awidth{1'bx}};
dout = {dwidth{1'bx}};
cyc = 1'b0;
stb = 1'bx;
we = 1'hx;
sel = {dwidth/8{1'bx}};
#1;
end
// Write data cycle
task wb_write;
input delay;
integer delay;
input [awidth -1:0] a;
input [dwidth -1:0] d;
begin
// Delay
repeat(delay) @(posedge clk);
// Set the signal value
#1;
adr = a;
dout = d;
cyc = 1'b1;
stb = 1'b1;
we = 1'b1;
sel = {dwidth/8{1'b1}};
@(posedge clk);
// Wait for the response signal from the slave node
while(~ack) @(posedge clk);
#1;
cyc = 1'b0;
stb = 1'bx;
adr = {awidth{1'bx}};
dout = {dwidth{1'bx}};
we = 1'hx;
sel = {dwidth/8{1'bx}};
end
endtask
// Read data cycle
task wb_read;
input delay;
integer delay;
input [awidth -1:0]a;
output [dwidth -1:0] d;
begin
// Delay
repeat(delay) @(posedge clk);
// Set the signal value
#1;
adr = a;
dout = {dwidth{1'bx}};
cyc = 1'b1;
stb = 1'b1;
we = 1'b0;
sel = {dwidth/8{1'b1}};
@(posedge clk);
// Wait for the slave node to answer the signal
while(~ack) @(posedge clk);
#1;
cyc = 1'b0;
stb = 1'bx;
adr = {awidth{1'bx}};
dout = {dwidth{1'bx}};
we = 1'hx;
sel = {dwidth/8{1'bx}};
d = din;
end
endtask
// Comparative data
task wb_cmp;
input delay;
integer delay;
input [awidth -1:0] a;
input [dwidth -1:0] d_exp;
begin
wb_read (delay, a, q);
if (d_exp !== q)
$display("Data compare error. Received %h, expected %h at time %t", q, d_exp,$time);
end
endtask
endmodule4.2 Simulation of slave nodes
The slave node emulator needs to simulate receiving data from the master node , And send a reply signal , The code is as follows :
`include "timescale.v"
// Module definition
module i2c_slave_model (scl, sda);
// Parameters
// Address
parameter I2C_ADR = 7'b001_0000;
// Input 、 Output
input scl;
inout sda;
// variable declaration
wire debug = 1'b1;
reg [7:0] mem [3:0]; // Initialize memory
reg [7:0] mem_adr; // Memory address
reg [7:0] mem_do; // Memory data output
reg sta, d_sta;
reg sto, d_sto;
reg [7:0] sr; // 8 Displacement bit register
reg rw; // Reading and writing
wire my_adr; // Address
wire i2c_reset; // RESET The signal
reg [2:0] bit_cnt;
wire acc_done; // Transmission complete
reg ld;
reg sda_o;
wire sda_dly;
// State definition of state machine
parameter idle = 3'b000;
parameter slave_ack = 3'b001;
parameter get_mem_adr = 3'b010;
parameter gma_ack = 3'b011;
parameter data = 3'b100;
parameter data_ack = 3'b101;
reg [2:0] state;
// Module body
// initialization
initial
begin
sda_o = 1'b1;
state = idle;
end
// Generate shift register
always @(posedge scl)
sr <= #1 {sr[6:0],sda};
// It is detected that the access address is consistent with the slave node
assign my_adr = (sr[7:1] == I2C_ADR);
// Generate bit register
always @(posedge scl)
if(ld)
bit_cnt <= #1 3'b111;
else
bit_cnt <= #1 bit_cnt - 3'h1;
// Generate access end flag
assign acc_done = !(|bit_cnt);
// sda Delay
assign #1 sda_dly = sda;
// Start state detected
always @(negedge sda)
if(scl)
begin
sta <= #1 1'b1;
if(debug)
$display("DEBUG i2c_slave; start condition detected at %t", $time);
end
else
sta <= #1 1'b0;
always @(posedge scl)
d_sta <= #1 sta;
// Stop status signal detected
always @(posedge sda)
if(scl)
begin
sto <= #1 1'b1;
if(debug)
$display("DEBUG i2c_slave; stop condition detected at %t", $time);
end
else
sto <= #1 1'b0;
// produce I2C Of RESET The signal
assign i2c_reset = sta || sto;
// State machine
always @(negedge scl or posedge sto)
if (sto || (sta && !d_sta) )
begin
state <= #1 idle; // reset State machine
sda_o <= #1 1'b1;
ld <= #1 1'b1;
end
else
begin
// initialization
sda_o <= #1 1'b1;
ld <= #1 1'b0;
case(state)
idle: // idle state
if (acc_done && my_adr)
begin
state <= #1 slave_ack;
rw <= #1 sr[0];
sda_o <= #1 1'b0; // Generate a response signal
#2;
if(debug && rw)
$display("DEBUG i2c_slave; command byte received (read) at %t",$time);
if(debug && !rw)
$display("DEBUG i2c_slave; command byte received (write) at %t",$time);
if(rw)
begin
mem_do <= #1 mem[mem_adr];
if(debug)
begin
#2 $display("DEBUG i2c_slave; data block read %x from address %x (1)", mem_do, mem_adr);
#2 $display("DEBUG i2c_slave; memcheck [0]=%x, [1]=%x, [2]=%x", mem[4'h0], mem[4'h1], mem[4'h2]);
end
end
end
slave_ack:
begin
if(rw)
begin
state <= #1 data;
sda_o <= #1 mem_do[7];
end
else
state <= #1 get_mem_adr;
ld <= #1 1'b1;
end
get_mem_adr: // Waiting for memory address
if(acc_done)
begin
state <= #1 gma_ack;
mem_adr <= #1 sr; // Save memory address
sda_o <= #1 !(sr <= 15); // Send a reply signal after receiving the legal address signal
if(debug)
#1 $display("DEBUG i2c_slave; address received. adr=%x, ack=%b",sr, sda_o);
end
gma_ack:
begin
state <= #1 data;
ld <= #1 1'b1;
end
data: // receive data
begin
if(rw)
sda_o <= #1 mem_do[7];
if(acc_done)
begin
state <= #1 data_ack;
mem_adr <= #2 mem_adr + 8'h1;
sda_o <= #1 (rw && (mem_adr <= 15) );
if(rw)
begin
#3 mem_do <= mem[mem_adr];
if(debug)
#5 $display("DEBUG i2c_slave; data block read %x from address %x (2)", mem_do, mem_adr);
end
if(!rw)
begin
mem[ mem_adr[3:0] ] <= #1 sr; // store data in memory
if(debug)
#2 $display("DEBUG i2c_slave; data block write %x to address %x", sr, mem_adr);
end
end
end
data_ack:
begin
ld <= #1 1'b1;
if(rw)
if(sda) //
begin
state <= #1 idle;
sda_o <= #1 1'b1;
end
else
begin
state <= #1 data;
sda_o <= #1 mem_do[7];
end
else
begin
state <= #1 data;
sda_o <= #1 1'b1;
end
end
endcase
end
// Read data from memory
always @(posedge scl)
if(!acc_done && rw)
mem_do <= #1 {mem_do[6:0], 1'b1};
// Produce three states
assign sda = sda_o ? 1'bz : 1'b0;
// Check the timing
wire tst_sto = sto;
wire tst_sta = sta;
wire tst_scl = scl;
// Specify the rising and falling edges of each signal
specify
specparam normal_scl_low = 4700,
normal_scl_high = 4000,
normal_tsu_sta = 4700,
normal_tsu_sto = 4000,
normal_sta_sto = 4700,
fast_scl_low = 1300,
fast_scl_high = 600,
fast_tsu_sta = 1300,
fast_tsu_sto = 600,
fast_sta_sto = 1300;
$width(negedge scl, normal_scl_low);
$width(posedge scl, normal_scl_high);
$setup(negedge sda &&& scl, negedge scl, normal_tsu_sta); // Start status signal
$setup(posedge scl, posedge sda &&& scl, normal_tsu_sto); // Stop status signal
$setup(posedge tst_sta, posedge tst_scl, normal_sta_sto);
endspecify
endmodule4.3 Simulation main program
The simulation master program completes the control from the master node data to the slave node , The code is as follows :
`include "timescale.v"
// Module definition
module tst_bench_top();
// Wiring and registers
reg clk;
reg rstn;
wire [31:0] adr;
wire [ 7:0] dat_i, dat_o;
wire we;
wire stb;
wire cyc;
wire ack;
wire inta;
//q Save the contents of the status register
reg [7:0] q, qq;
wire scl, scl_o, scl_oen;
wire sda, sda_o, sda_oen;
// Register address
parameter PRER_LO = 3'b000; // Low address of frequency division register
parameter PRER_HI = 3'b001; // High address
parameter CTR = 3'b010; // Control register address ,(7) Enable bit |6 Interrupt enable bit |5-0 The remaining reserved bits
parameter RXR = 3'b011; // Receive register address ,(7) The last byte of data received
parameter TXR = 3'b011; // Transfer register address ,(7) The last bit when transmitting the address is the read / write bit ,1 For reading
parameter CR = 3'b100; // Command register address ,
//(7) Start |6 end |5 read |4 Write |3 The reply ( As receiver , Send reply signal ,“0” Answer for ,“1” For not answering )|2 Keep a |1 Keep a |0 Interrupt reply bit , These eight bits are automatically cleared
parameter SR = 3'b100; // Status register address ,(7) Receive response bit (“0” To receive a reply )|6 Busy bit ( After the start signal is generated, it becomes 1, After the end signal, it changes to 0)|5 Arbitration seat |4-2 Keep a |1 Transmit median (1 Indicates that data is being transferred ,0 Indicates the end of transmission )| Interrupt flag bit
parameter TXR_R = 3'b101;
parameter CR_R = 3'b110;
// Generate a clock signal , A unit of time is 1ns, The period is 10ns, The frequency is 100MHz.
always #5 clk = ~clk;
// Connect master Analog modules
wb_master_model #(8, 32) u0 (
.clk(clk), // The clock
.rst(rstn), // Lifting
.adr(adr), // Address
.din(dat_i), // Input data
.dout(dat_o), // Output data
.cyc(cyc),
.stb(stb),
.we(we),
.sel(),
.ack(ack), // The reply
.err(1'b0),
.rty(1'b0)
);
// Connect i2c Interface
i2c_master_top i2c_top (
// Connect to master Analog module section
.wb_clk_i(clk), // The clock
.wb_rst_i(1'b0), // Synchronous restart bit
.arst_i(rstn), // Asynchronous restart
.wb_adr_i(adr[2:0]), // Address input
.wb_dat_i(dat_o), // Data input interface
.wb_dat_o(dat_i), // Data is output from the interface
.wb_we_i(we), // Write enable signal
.wb_stb_i(stb), // Piece of optional signal , It should always be high
.wb_cyc_i(cyc),
.wb_ack_o(ack), // The reply signal is output to master Analog modules
.wb_inta_o(inta), // The interrupt signal is output to master Analog modules
// Output i2c The signal , Connect to slave Analog modules
.scl_pad_i(scl),
.scl_pad_o(scl_o),
.scl_padoen_o(scl_oen),
.sda_pad_i(sda),
.sda_pad_o(sda_o),
.sda_padoen_o(sda_oen)
);
// Connect to slave Analog modules
i2c_slave_model #(7'b1010_000) i2c_slave (
.scl(scl),
.sda(sda)
);
// by master The analog module generates scl and sda Tristate buffer for
assign scl = scl_oen ? 1'bz : scl_o; // create tri-state buffer for i2c_master scl line
assign sda = sda_oen ? 1'bz : sda_o; // create tri-state buffer for i2c_master sda line
// Pull up
pullup p1(scl); // pullup scl line
pullup p2(sda); // pullup sda line
// initialization
initial
begin
$display("\n state : %t I2C Start of interface test !\n\n", $time);
// Initial value
clk = 0;
// Lifting system
rstn = 1'b1; // negate reset
#2;
rstn = 1'b0; // assert reset
repeat(20) @(posedge clk);
rstn = 1'b1; // negate reset
$display(" state : %t Complete system restart !", $time);
@(posedge clk);
// Programming the interface
// Write internal register
// frequency division 100M/100K*5=O'200=h'C8
u0.wb_write(1, PRER_LO, 8'hc7);
u0.wb_write(1, PRER_HI, 8'h00);
$display(" state : %t Complete the frequency division register operation !", $time);
// Read the contents of the frequency division register
u0.wb_cmp(0, PRER_LO, 8'hc8);
u0.wb_cmp(0, PRER_HI, 8'h00);
$display(" state : %t Complete the frequency division register confirmation operation !", $time);
// Interface enable
u0.wb_write(1, CTR, 8'h80);
$display(" state : %t Complete interface enablement !", $time);
// drive slave Address
// h'a0=b'1010_0000, Address + Write status , The address written is h'50
u0.wb_write(1, TXR, 8'ha0);
// The order is b'1001_0000, Generate start bit , And set the write status
u0.wb_write(0, CR, 8'h90);
$display(" state : %t Generate start bit , Then write the order a0( Address + Write ), Command start !", $time);
// Check status bit information
// Check whether the transmission ends
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(0, SR, q);
$display(" state : %t Address driven write operation completed !", $time);
// The address to be written is h'01
u0.wb_write(1, TXR, 8'h01);
// Generate a write command b'0001_0000
u0.wb_write(0, CR, 8'h10);
$display(" state : %t The address to be written is 01, Command start !", $time);
// Check the status bit
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(0, SR, q);
$display(" state : %t Write operation complete !", $time);
// Write content
u0.wb_write(1, TXR, 8'ha5);
u0.wb_write(0, CR, 8'h10);
$display(" state : %t The writing content is a5, Start writing process !", $time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q);
$display(" state : %t Write a5 To the address h'01 Finish in !", $time);
// Write the next address 5a
u0.wb_write(1, TXR, 8'h5a); // present data
// Write and stop
u0.wb_write(0, CR, 8'h50); // set command (stop, write)
$display(" state : %t Write 5a To the next address , Generate stop bit !", $time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q); // poll it until it is zero
$display(" state : %t Write the second address to finish !", $time);
// read
// drive slave Address
u0.wb_write(1, TXR, 8'ha0);
u0.wb_write(0, CR, 8'h90);
$display(" state : %t Generate start bit , Write orders a0 (slave Address +write)", $time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q); // poll it until it is zero
$display(" state : %t slave Address drive complete !", $time);
// Sending address
u0.wb_write(1, TXR, 8'h01);
u0.wb_write(0, CR, 8'h10);
$display(" state : %t Sending address 01!", $time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q);
$display(" state : %t Address sending completed !", $time);
// drive slave Address ,1010_0001,h'50+read
u0.wb_write(1, TXR, 8'ha1);
u0.wb_write(0, CR, 8'h90);
$display(" state : %t Generate repeat start bit , Read the address + Start bit ", $time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q);
$display(" state : %t The order is over !", $time);
// Reading data
u0.wb_write(1, CR, 8'h20);
$display(" state : %t read + Answer command ", $time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q);
$display(" state : %t End of reading !", $time);
// Check what you read
u0.wb_read(1, RXR, qq);
if(qq !== 8'ha5)
$display("\n error : What is needed is a5, received %x at time %t", qq, $time);
// Read the contents of the next address
u0.wb_write(1, CR, 8'h20);
$display(" state : %t read + The reply ", $time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q);
$display(" state : %t The second address reading is over !", $time);
u0.wb_read(1, RXR, qq);
if(qq !== 8'h5a)
$display("\n error : What is needed is 5a, received %x at time %t", qq, $time);
// read
u0.wb_write(1, CR, 8'h20);
$display(" state : %t read + The reply ", $time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q);
$display(" state : %t The third address is read !", $time);
u0.wb_read(1, RXR, qq);
$display(" state : %t The third address is %x !", $time, qq);
// read
u0.wb_write(1, CR, 8'h28);
$display(" state : %t read + No answer !", $time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q);
$display(" state : %t The fourth address is read !", $time);
u0.wb_read(1, RXR, qq);
$display(" state : %t The fourth address is %x !", $time, qq);
// Check for nonexistent slave Address
// drive slave address
u0.wb_write(1, TXR, 8'ha0);
u0.wb_write(0, CR, 8'h90);
$display(" state : %t Generate start bit , dispatch orders a0 (slave Address + Write ). Check for illegal addresses !",$time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q); // poll it until it is zero
$display(" state : %t The order is over !", $time);
// Send memory address
u0.wb_write(1, TXR, 8'h10);
u0.wb_write(0, CR, 8'h10);
$display(" state : %t send out slave Memory address 10!", $time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q);
$display(" state : %t The address has been sent !", $time);
// slave Send no reply
$display(" state : %t Check the unacknowledged bit !", $time);
if(!q[7])
$display("\n error : need NACK, Received ACK\n");
// from slave Reading data
u0.wb_write(1, CR, 8'h40);
$display(" state : %t produce 'stop' position ", $time);
u0.wb_read(1, SR, q);
while(q[1])
u0.wb_read(1, SR, q); // poll it until it is zero
$display(" state : %t end !", $time);
#25000; // wait 25us
$display("\n\n state : %t End of test !", $time);
$finish;
end
endmodule4.4 Simulation results
stay ModelSim The simulation results can be seen in . Pictured 7 It shows the sending start status and write the address “a0” Graphics when , At this time, it is shown as SCL At high SDA A falling edge of , And then there's the data “1010,0000”.
chart 7 Send start signal and write address a0
Pictured 8 Sending data is shown “01” and “a5” Graphics when , It is shown on the figure as : data “0000,0001” and “1010,0101”.
chart 8 send data “01” and “a5”
Pictured 9 It is shown that the transmission stop status signal and data “5a” Graphics when , It is shown on the figure as SCL At high SDA A rising edge of , And then there's the data “0101,1010”.
chart 9 Send stop status signal and data “5a”
Simulation program description I²C Procedure compliance I²C Protocol timing and data format , Simulation can be realized I²C The task of the agreement .
This chapter first explains I²C The contents of the agreement , This paper introduces the basic concept of the protocol, the specific meaning of data transmission commands and the requirements of the protocol for timing . Next, the simulation I²C Framework of protocol procedure , Explain in detail the functions of each module in the framework and introduce the detailed code . Finally, a completed simulation program is used to test the program .I²C It has a wide range of applications , This article hopes to provide you with a feasible solution through this example .
This is the end of this article , Great Xia , I'll see you again ! END
It will be updated continuously in the future , bring Vivado、 ISE、Quartus II 、candence Installation related design tutorial , Learning resources 、 Project resources 、 Good article recommendation and so on , I hope great Xia will continue to pay attention to .
Heroes , The world is so big , Keep going , May everything be well , I'll see you again !
边栏推荐
- PCL Library - error reporting solution: cmake and Anaconda conflicts during installation
- 洛谷_P1008 [NOIP1998 普及组] 三连击_枚举
- Design of digital video signal processor based on FPGA (with main code)
- Programming skills: script scheduling
- 522. 最长特殊序列 II / 剑指 Offer II 101. 分割等和子集
- Handling methods for NVIDIA deepstream running delay, jamming and crash
- 16 -- 删除无效的括号
- Brief reading of dynamic networks and conditional computing papers and code collection
- 直播app运营模式有哪几种,我们该选择什么样的模式?
- 数学建模经验分享:国赛美赛对比/选题参考/常用技巧
猜你喜欢

Creation and use of static library (win10+vs2022

Teach you how to realize pynq-z2 bar code recognition

Interpretation of new version features of PostgreSQL 15 (including live Q & A and PPT data summary)

Computer screen splitting method

sql注入原理

Reflection learning summary

Hyperledger Fabric 2. X custom smart contract

Top ten Devops best practices worthy of attention in 2022

Atomic operation class

QT notes (XXVIII) using qwebengineview to display web pages
随机推荐
R language triple becomes matrix matrix becomes triple
我想买固收+产品,但是不了解它主要投资哪些方面,有人知道吗?
隱私計算FATE-離線預測
Google tool splits by specified length
my. INI file configuration
522. 最长特殊序列 II / 剑指 Offer II 101. 分割等和子集
[issue 17] golang's one-year experience in developing Meitu
Leetcode 724. 寻找数组的中心下标(可以,一次过)
February 16, 2022 freetsdb compilation and operation
Nvidia Deepstream 运行延迟,卡顿,死机处理办法
Professor huangxutao, a great master in CV field, was born at the age of 86. UIUC specially set up a doctoral scholarship to encourage cutting-edge students
How to change a matrix into a triple in R language (i.e. three columns: row, col, value)
About sitemap XML problems
522. longest special sequence II / Sword finger offer II 101 Split equal sum subset
Pisa-Proxy 之 SQL 解析实践
Introduction to TTCAN brick moving
[an Xun cup 2019]attack
Make a ThreadLocal (source code) that everyone can understand
CV领域一代宗师黄煦涛教授86岁冥诞,UIUC专设博士奖学金激励新锐
E-week finance Q1 mobile banking has 650million active users; Layout of financial subsidiaries in emerging fields