芯片跨时钟域传输总结

文摘   2024-11-11 20:07   四川  

一、单比特CDC传输1.1 慢到快

快时钟域相比慢时钟域采样速度更快,也就是说从慢时钟域来到快时钟域的信号一定可以被采集到。既然快时钟一定可以采集到慢时钟分发的数据,那么考虑的问题就只剩下如何保证采样到的信号质量!最常用的同步方法是双级触发器缓存法,俗称延迟打拍法。信号从一个时钟域进入另一个时钟域之前,将该信号用两级触发器连续缓存两次,可有效降低因为时序不满足而导致的亚稳态问题。

具体如下图所示:来自慢时钟clk1的信号在clk2被多次采样(信号在clk1持续一个时钟周期,在clk2持续三个时钟周期),如果只需要在clk2持续一个时钟周期,可以采用边沿检测即可得到signal4;

1.2 快到慢

慢时钟域相比快时钟域采样速度更慢,也就是说从快时钟域来到慢时钟域的信号极有可能被漏采。一般要求在接收时钟域中采样信号要保持三个时钟边沿的时间(也就是1.5倍的采样时钟周期)才会避免出现漏采。也就是快到慢跨时钟域的核心是如何延长信号长度!

对于电平信号而言(一般电平信号持续时间足够长),信号长度可以得到保证,所以正常采用两级同步器采样即可。

对于脉冲信号而言(一般脉冲信号持续时间很短),长度难以得到保证,需要对信号进行延长。目前,常用延长方法有两种:

一是开环(无反馈)延长,在知道两个时钟频率比的情况下,可以采用“快时钟域脉宽扩展+慢时钟域延迟打拍”的方法进行同步。

二是闭环(有反馈)延长,信号延长的恢复位置由反馈信号决定,此方法实质是通过相互握手的方式对窄脉冲信号进行脉宽扩展,这也是我们常说的“握手协议”。

然而,除了“握手协议”以外其他两种方法都是有缺陷、有限制的,具体如下图所示:

可以看到无论是电平还是脉冲信号使用起来都是有限制的,因为它们采用的都是无反馈的开环设计(详细可查看博文跨时钟传输——单比特)。采用闭环的反馈设计可以避免这些问题,具体流程如下:

快时钟域对脉冲信号进行检测,检测为高电平时输出高电平信号req。

慢时钟域对快时钟域的信号req进行延迟打拍采样。因为此时的脉冲信号被快时钟域保持拉高状态,延迟打拍肯定会采集到该信号。

慢时钟域确认采样得到高电平信号req_r2后,拉高反馈信号ack再反馈给快时钟域。

快时钟域对反馈信号ack进行延迟打拍采样得到ack_r0。如果检测到反馈信号为高电平,证明慢时钟域已经接收到有效的高电平信号,信号恢复原来状态。

1.3 单比特“握手协议”verilog代码

verilog代码

代码语言:c

复制

//单比特快到慢“握手协议”

module cdc_sbit_handshake(

input aclk, //快时钟

input arst_n, //快时钟域复位信号

input signal_a,//快时钟域信号

input bclk, //慢时钟

input brst_n, //慢时钟域复位信号

output signal_b//慢时钟域输出信号

);


//慢时钟域信号展宽直至反馈信号回来再恢复

reg   req;//寄存慢时钟域展宽信号

reg   ack_r0;//反馈信号

always@(posedge aclk or negedge arst_n) begin

if(!arst_n) begin

req <= 1'b0;

end

else if(signal_a) begin

req <= 1'b1; //信号展宽

end

else if(ack_r0) begin

req <= 1'b0; //反馈信号到来时恢复

end

end

//展宽信号跨时钟同步至慢时钟域

reg   req_r0;

reg   req_r1;

reg   req_r2;

always@(posedge bclk or negedge brst_n) begin

if(!brst_n)begin

{req_r2,req_r1,req_r0} <= 3'b0;

end

else begin

{req_r2,req_r1,req_r0} <=  {req_r1,req_r0,req};

end

end

//生成反馈信号并同步至快时钟域

reg   ack;

always@(posedge aclk or negedge arst_n) begin

if(!arst_n) begin

{ack_r0,ack} <= 2'b0;

end

else begin

{ack_r0,ack} <=  {ack,req_r1};

end

end

//信号上升沿检测,让输出持续一个慢时钟周期

assign signal_b = ~req_r2 & req_r1;

endmodule

Testbench

代码语言:c

复制

`timescale 1ns/1ps //仿真时间单位1ns 仿真时间精度1ps

module cdc_sbit_handshake_tb;

//信号申明

reg aclk;

reg arst_n;

reg signal_a;

reg bclk;

reg brst_n;

wire signal_b;

//例化

cdc_sbit_handshake u_cdc_sbit_handshake(

.aclk (aclk),

.bclk (bclk),

.arst_n (arst_n),

.brst_n (brst_n),

.signal_a (signal_a),

.signal_b (signal_b)

);

//快时钟域慢时钟生成

always #5  aclk =~ aclk;

always #15 bclk =~ bclk;

//初始信号赋值与激励

initial begin

signal_a = 0;

aclk = 0;

bclk = 0;

arst_n = 1;

brst_n = 1;

#15;

arst_n = 0;

brst_n = 0;

#15;

arst_n = 1;

brst_n = 1;

signal_a = 1;

#10;

signal_a = 0;

end

endmodule

仿真结果

二、多比特CDC传输

多比特为能不能使用二级同步器传输?使用格雷码也不行吗?什么情况下可以使用同步器加格雷码跨时钟传输?

先给结论:多比特信号不能用二级同步器跨时钟传输,哪怕使用格雷码大部分情况也不行,只有在格雷码自增或自减顺序变化才可以跨时钟传输。对于多比特数据,在进行传输时候会因为时序问题导致所有寄存器不会同时翻转(不是不翻转,是不同时翻转!),所以容易在跨时钟传输的时候出现中间态。使用格雷码可以避免这种现象,但是当格雷码不是按计数顺序变化(非顺序变化相当于每次变化不止一位),这同样是不允许的,因为格雷码每次只有一位发生变化的前提是,数据是递增或递减的。比如异步FIFO中格雷码可以通过二级同步器进行CDC传输。

2.1 慢到快:MUX同步器法

慢到快这种情况在快时钟接收端是一定能够采样得到的,但是根据上文可知,多比特不适合采用二级同步器直接传输采样,因为在传输过程中有多位同时变化,那么有什么解决办法呢?解决办法是在传输过程中不变化!所以必须在写入使能信号有效时传输!

传输非同步数据到接收时钟域时配上一个同步的控制信号,数据和控制信号被同时发送到接收时钟域,同时控制信号在接收时钟域使用两级寄存器同步到接收时钟域,使用此同步后的控制信号来加载数据,这样数据就可以在目的寄存器被安全加载。

具体代码可参考链接:Verilog 跨时钟域传输:慢到快

verilog代码

代码语言:c

复制

//同步模块工作时钟为 100MHz 的模块

//异步数据对来自工作时钟为 20MHz 的模块

module delay_sample(

input               rstn,

input               clk1,

input [31:0]        din,

input               din_en,

input               clk2,

output [31:0]       dout,

output              dout_en);

//sync din_en

reg [2:0]    din_en_r ;

always @(posedge clk2 or negedge rstn) begin

if (!rstn) din_en_r  <= 3'b0 ;

else       din_en_r  <= {din_en_r[1:0], din_en} ;

end

wire din_en_pos = din_en_r[1] && !din_en_r[2] ;

//sync data

reg [31:0]           dout_r ;

reg                  dout_en_r ;

always @(posedge clk2 or negedge rstn) begin

if (!rstn)

dout_r         <= 'b0 ;

else if (din_en_pos)

dout_r         <= din ;

end

//dout_en delay

always @(posedge clk2 or negedge rstn) begin

if (!rstn)        dout_en_r      <= 1'b0 ;

else              dout_en_r      <= din_en_pos ;

end

assign       dout    = dout_r ;

assign       dout_en = dout_en_r ;

endmodule

时序结构如下图所示:

但如果慢时钟域没有数据使能信号 din_en, 或数据使能信号一直有效,此时在快时钟域对数据使能信号进行上升沿检测的方法将会失效。因为数据使能信号一直有效,除了第一个数据,快时钟域将无法检测到后继数据的传输时刻。

解决方法就是,在快时钟域对慢时钟信号的边沿进行检测。

2.2 快到慢:握手协议

快到慢必然会伴随着漏采的风险,根据单比特CDC传输的方法可以知道避免的方法就是延长信号的长度,所以需要带写入的使能信号对信号进行延长。此处任采用握手的方式,完全握手具体原理如下图所示:



优点:可以解决快时钟域向慢时钟域过渡的问题,且其适用的范围很广。

缺点:实现较为复杂,特别是其效率不高,在对设计性能要求较高的场合应该慎用。

这一部分具体可以查看链接:FPGA学习笔记——跨时钟域(CDC)设计之多bit信号同步

verilog代码

代码语言:c

复制

module  data_driver(

input      clk_a,     //发送端时钟信号

input      rst_n,    //复位信号,低电平有效

input      data_ack, //数据接收确人信号

input             clk_b,   //接收端时钟信号

input             rst_n,   //复位信号,低电平有效

input    [3:0]    data,    //接收数据

input             data_req,    //请求接收信号

output   reg      data_ack//数据接收确人信号

);

/********************** 发送端 **********************/

reg    [3:0]    data; //发送数据

reg     data_req ;      //请求接收信号

reg    [2:0]    cnt_reg;

reg             data_ack_sync1;

reg             data_ack_sync2;

//计数

always@(posedge clk_a or negedge rst_n)

begin

if(!rst_n)

cnt_reg <= 3'd0;

else if(data_ack_sync1 && !data_ack_sync2 == 1'b1)

cnt_reg <= 3'd0;

else if(data_req == 1'b1)

cnt_reg <= cnt_reg;

else

cnt_reg <= cnt_reg + 1'b1;

end

//data_ack两级同步

always@(posedge clk_a or negedge rst_n)

begin

if(!rst_n)

begin

data_ack_sync1 <= 1'b0;

data_ack_sync2 <= 1'b0;

end

else

begin

data_ack_sync1 <= data_ack;

data_ack_sync2 <= data_ack_sync1;

end

end

//请求接收信号

always@(posedge clk_a or negedge rst_n)

begin

if(!rst_n)

data_req <= 1'b0;

else if(cnt_reg == 3'd4)

data_req <= 1'b1;

else if(data_ack_sync2 == 1'b1)

data_req <= 1'b0;

else

data_req <= data_req;

end

//发送数据

always@(posedge clk_a or negedge rst_n)

begin

if(!rst_n)

data <= 4'd0;

else if(data == 4'd7 && data_ack_sync2 == 1'b1 && data_req == 1'b1 )

data <= 4'd0;

else

begin

if(data_ack_sync2 == 1'b1 && data_req == 1'b1 )

data <= data + 1'b1;

else

data <= data;

end

end

/********************** 接收端 **********************/

reg             data_req_sync1;

reg             data_req_sync2;

//data_req两级同步

always@(posedge clk_b or negedge rst_n)

begin

if(!rst_n)

begin

data_req_sync1 <= 1'b0;

data_req_sync2 <= 1'b0;

end

else

begin

data_req_sync1 <= data_req;

data_req_sync2 <= data_req_sync1;

end

end

//数据接收确人信号

always@(posedge clk_b or negedge rst_n)

begin

if(!rst_n)

data_ack <= 1'b0;

else if(data_req_sync2 == 1'b1)

data_ack <= 1'b1;

else

data_ack <= 1'b0;

end

endmodule2.3 异步FIFO(慢到快和快到慢通杀)

关于异步FIFO具体可以看看这篇:异步FIFO设计原理与设计方法以及重要问题汇总(包含verilog代码|Testbench|仿真结果),对异步FIFO介绍很详细并且总结了若干重要问题。

FIFO 是一种“先进先出队列”,数据从一头写入,从另一头读出,读出顺序和写入顺序一模一样。因为队列空间有限,因此一般把队列设计为环形。对于队列来说,最重要的事情是不能在队空的时候读数、不能在队满的时候写数。一般通过比较读写指针来获得“队空”和“队满”信息。异步FIFO常常用在高速数据跨时钟域的场景上。

异步FIFO主要由五部分组成:RAM、写控制端、读控制端、两个时钟同步端

双端口RAM:此处为伪双端口RAM进行数据存储与读出,有两组数据线、地址线、时钟线。

写控制端:写指针与满信号产生器,用于判断是否可以写入数据,写操作时,写使能有效且FIFO未满。

读控制端:读指针与空信号产生器,用于判断是否可以读取数据,读操作时,读使能有效且FIFO未空。

两个时钟同步端:读指针同步到写指针域进行“写满”判断,写指针同步到读指针域进行“读空”判断。

verilog代码

代码语言:c

复制

//深度为8,数据位宽为8的异步FIFO

module async_fifo #(

parameter   DATA_DEPTH = 8, //深度为8

parameter   DATA_WIDTH = 8, //数据位宽为8

parameter   PTR_WIDTH  = 3 //读写指针位宽为3

)(

input  [DATA_WIDTH - 1 : 0] wr_data, //写数据

input                   wr_clk, //写时钟

input                   wr_rst_n, //写时钟复位

input                   wr_en, //写使能

input                   rd_clk, //读数据

input                   rd_rst_n, //读时钟复位

input                   rd_en, //读使能

output reg                 fifo_full, //“满”标志位

output reg                 fifo_empty, //“空”标志位

output reg [DATA_WIDTH - 1 : 0] rd_data //写时钟

);

/*-----------------------------------------------------------------

-----------------------------伪双口RAM模块--------------------------

------------------------------------------------------------------*/

//定义一个宽度为8,深度为DEPTH的8的RAM_FIFO

reg [DATA_WIDTH - 1 : 0] ram_fifo [DATA_DEPTH - 1 : 0];

//写指针计数

reg [PTR_WIDTH : 0]  wr_ptr; //信息位+地址位所以指针位宽为4

always@ (posedge wr_clk or negedge wr_rst_n) begin

if(!wr_rst_n) begin

wr_ptr <= 0;

end

else if(wr_en && !fifo_full) begin

wr_ptr <= wr_ptr + 1;

end

else begin

wr_ptr <= wr_ptr;

end

end

//RAM写入数据

wire [PTR_WIDTH -1 : 0]  wr_addr;

assign wr_addr = wr_ptr[PTR_WIDTH -1 : 0]; //RAM写数据只需要地址位不需要信息位,所以寻址地址位宽为3

always@ (posedge wr_clk or negedge wr_rst_n) begin

if(!wr_rst_n) begin

ram_fifo[wr_addr] <= 0; //复位

end

else if(wr_en && !fifo_full) begin

ram_fifo[wr_addr] <= wr_data; //数据写入

end

else begin

ram_fifo[wr_addr] <= ram_fifo[wr_addr]; //保持不变

end

end

//读指针计数

reg [PTR_WIDTH : 0]  rd_ptr;

always@ (posedge rd_clk or negedge rd_rst_n) begin

if(!rd_rst_n) begin

rd_ptr <= 0;

end

else if(rd_en && !fifo_empty) begin

rd_ptr <= rd_ptr + 1;

end

else begin

rd_ptr <= rd_ptr;

end

end

//RAM读出数据

wire [PTR_WIDTH -1 : 0]  rd_addr;

assign rd_addr = rd_ptr[PTR_WIDTH -1 : 0];//RAM读数据只需要地址位不需要信息位,所以寻址地址位宽为3

always@ (posedge rd_clk or negedge rd_rst_n) begin

if(!rd_rst_n) begin

rd_data <= 0; //复位

end

else if(rd_en && !fifo_empty) begin

rd_data <= ram_fifo[rd_addr]; //读数据

end

else begin

rd_data <= rd_data; //保持不变

end

end

/*--------------------------------------------------------------------

------------------------读写指针(格雷码)转换与跨时钟域同步模块------

---------------------------------------------------------------------------------------*/

//读写指针转换成格雷码

wire [PTR_WIDTH : 0] wr_ptr_gray;

wire [PTR_WIDTH : 0] rd_ptr_gray;

assign wr_ptr_gray = wr_ptr ^ (wr_ptr >> 1);

assign rd_ptr_gray = rd_ptr ^ (rd_ptr >> 1);

//写指针同步到读时钟域

//打两拍

reg [PTR_WIDTH : 0] wr_ptr_gray_r1;

reg [PTR_WIDTH : 0] wr_ptr_gray_r2;

always@ (posedge rd_clk or negedge rd_rst_n) begin

if(!rd_rst_n) begin

wr_ptr_gray_r1 <= 0;

wr_ptr_gray_r2 <= 0;

end

else begin

wr_ptr_gray_r1 <= wr_ptr_gray;

wr_ptr_gray_r2 <= wr_ptr_gray_r1;

end

end

//读指针同步到写时钟域

//打两拍

reg [PTR_WIDTH : 0] rd_ptr_gray_r1;

reg [PTR_WIDTH : 0] rd_ptr_gray_r2;

always@ (posedge wr_clk or negedge wr_rst_n) begin

if(!wr_rst_n) begin

rd_ptr_gray_r1 <= 0;

rd_ptr_gray_r2 <= 0;

end

else begin

rd_ptr_gray_r1 <= rd_ptr_gray;

rd_ptr_gray_r2 <= rd_ptr_gray_r1;

end

end

/*--------------------------------------------------------------------------------------

--------------------------------------空满信号判断模块-----------------------------------

---------------------------------------------------------------------------------------*/

//组合逻辑判断写满

always@ (*) begin

if(!wr_rst_n) begin

fifo_full <= 0;

end

else if( wr_ptr_gray == { ~rd_ptr_gray_r2[PTR_WIDTH : PTR_WIDTH - 1],

rd_ptr_gray_r2[PTR_WIDTH - 2 : 0] }) begin

fifo_full <= 1;

end

else begin

fifo_full <= 0;

end

end

//组合逻辑判断读空

always@ (*) begin

if(!rd_rst_n) begin

fifo_empty <= 0;

end

else if(rd_ptr_gray == wr_ptr_gray_r2) begin

fifo_empty <= 1;

end

else begin

fifo_empty <= 0;

end

end

endmodule

Testbench

代码语言:c

复制

`timescale 1ns/1ps;//仿真时间单位1ns 仿真时间精度1ps

module async_fifo_tb #(

parameter   DATA_DEPTH = 8,

parameter   DATA_WIDTH = 8,

parameter   PTR_WIDTH  = 3

);

//信号申明

reg  [DATA_WIDTH - 1 : 0] wr_data;

reg                   wr_clk;

reg                   wr_rst_n;

reg                   wr_en;

reg                   rd_clk;

reg                   rd_rst_n;

reg                   rd_en;

wire                 fifo_full;

wire                 fifo_empty;

wire [DATA_WIDTH - 1 : 0] rd_data;

//例化

async_fifo u_async_fifo (

.wr_clk (wr_clk),

.rd_clk (rd_clk),

.wr_rst_n (wr_rst_n),

.rd_rst_n (rd_rst_n),

.wr_en (wr_en),

.rd_en (rd_en),

.wr_data (wr_data),

.rd_data (rd_data),

.fifo_empty (fifo_empty),

.fifo_full (fifo_full)

);

//读写时钟信号生成

always #10 rd_clk = ~rd_clk;

always #5  wr_clk = ~wr_clk;

//信号初始化和赋值

initial begin

wr_clk = 0;

wr_rst_n = 1;

wr_en = 0;

rd_clk = 0;

rd_rst_n = 1;

rd_en = 0;

#10;

wr_rst_n = 0;

rd_rst_n = 0;

#10;

wr_rst_n = 1;

rd_rst_n = 1;

//only write

wr_en = 1;

rd_en = 0;

repeat(10) begin

@(negedge wr_clk) begin

wr_data = {$random}%30;

end

end

//only read

wr_en = 0;

rd_en = 1;

repeat(10) begin

@(negedge rd_clk);

end

rd_en =0;

//read and write

wr_en = 0;

rd_en = 0;

#80;

wr_en = 1;

rd_en = 1;

repeat(20) begin

@(negedge wr_clk) begin

wr_data = {$random}%30;

end

end

end

endmodule

仿真结果

三、CDC的几个重要问题(重要!!!)

多比特为能不能使用二级同步器传输?使用格雷码也不行吗?什么情况下可以使用同步器加格雷码跨时钟传输?

先给结论:多比特信号不能用二级同步器跨时钟传输,哪怕使用格雷码大部分情况也不行,只有在格雷码自增或自减顺序变化才可以跨时钟传输。对于多比特数据,在进行传输时候会因为时序问题导致所有寄存器不会同时翻转(不是不翻转,是不同时翻转!),所以容易在跨时钟传输的时候出现中间态。使用格雷码可以避免这种现象,但是当格雷码不是按计数顺序变化(非顺序变化相当于每次变化不止一位),这同样是不允许的,因为格雷码每次只有一位发生变化的前提是,数据是递增或递减的。比如异步FIFO中格雷码可以通过二级同步器进行CDC传输。

慢到快使用打两拍的前提是什么?先给结论:两级同步器与慢时钟域之间无组合逻辑,因为组合逻辑里存在竞争冒险,从而导致毛刺产生。我们无法预先知道CLKB 的上升沿何时会到来,CLKB 采样到的信号就无法预知。

仅仅通过简单的同步器同步有可能是不安全的,那么如何传递两个同时需要的信号(b_load和b_en)?

将b_load和b_en信号在b_clk时钟域中合并成一个信号b_lden,然后同步至a_clk中。若果不能合并,比如译码信息则加入一个控制信号,等两个信号稳定了再采样!

四、总结(重要)

采样中“快到慢”与“慢到快”在考虑问题时有什么区别?慢到快:只需要考虑亚稳态问题.
快到慢:除亚稳态问题外,还需考虑慢时钟的采样速率问题。因为根据采样定理,采样频率低于信号最高频率2倍的时候,是无法完整采样的。

CDC传输方法总结:单比特:

慢到快只考虑亚稳态问题,采用延迟打拍法;

快到慢还需要考虑慢时钟采样速度,但是只要延长信号长度即可。常用方法为电平同步器、脉冲同步器、握手协议。其中,握手协议限制较为灵活,但握手信号需要在两个时钟域来回传递导致延时很大,所以握手协议是以牺牲效率为代价保证信号传递质量。

多比特:

慢到快:只考虑亚稳态问题,采用延迟打拍法。为需要传输的数据配上一个同步的控制使能信号,数据和控制信号被同时发送到接收时钟域,使用此同步后的控制信号来加载数据(控制信号有效表示数据稳定不变化从而避免传输出错),这样数据就可以在目的寄存器被安全加载。这种方法我们称为MUX同步器法/多周期路径同步法(意思都差不多)。

快到慢:因为考虑时钟采样速度,所以需要延长(使能信号)信号长度。最常用的还是“握手协议”,将使能信号同步后再加载多比特数据。

处理多比特数据跨时钟传输,最常用还是异步FIFO,

一来异步FIFO同时适用快到慢和慢到快两种CDC传输;

二来也能更好地满足数据流具有较快的传输速度要求。

转载原文链接:https://cloud.tencent.com/developer/article/2294982

景芯SoC v4.0芯片全流程实战


终身辅导、一对一辅导是景芯SoC训练营的特色!

手把手教您搭建SoC,从入门到进阶,带您掌握架构、算法、设计、验证、DFT、后端全流程低功耗!直播视频不定期升级!让您快速超越同龄人!

报名微信:13541390811


景芯全流程课程如下:

  • 景芯SoC设计  视频+文档+实战+一对一终身辅导(视频免费无期限)

  • 景芯SoC验证  视频+文档+实战+一对一终身辅导视频免费无期限

  • 景芯SoC中端  视频+文档+实战+一对一终身辅导视频免费无期限

  • 景芯SoC后端  视频+文档+实战+一对一终身辅导视频免费无期限


进阶课程:

  • 12nm 2.5GHz A72 低功耗DVFS实战培训(价格不到同行1/2)

  • DDR4/3项目实战培训(价格不到同行1/2)



小编逐步将教程、芯片设计全流程知识公布在知识星球,包括设计、验证、DFT、后端全流程知识以及大量技术文档,如果你和我一样渴求知识,不惧怕全流程的知识爆炸,那么欢迎您加入讨论学习,共同进步!



景芯主营业务是design service+一对一芯片辅导培训!


另外小编团队提供芯片Design Service,设计服务包括:

  • 提供SoC、MCU、ISP、CIS等芯片设计、验证、DFT设计服务

  • 提供DDR/PCIE/MIPI/CAN/USB/ETH/QSPI/UART/I2C等IP设计

  • 提供7nm、12nm、28nm、40nm、55nm、65nm、90nm等后端设计

  • 提供高校、企业定制化芯片设计服务、设计培训业务


景芯SoC v4.0芯片全流程实战训练营的宗旨:

手把手教您掌握SoC算法、设计、验证、DFT、后端全流程低功耗!


景芯SoCv3.0,是一款用于【芯片全流程实战培训】的低功耗多媒体SoC!

景芯SoC系统分为三个层次的功耗管理,并集成低功耗RISC-V处理器,集成ITCM SRAM、DTCM SRAM,集成MIPI、ISP、USB、QSPI、UART、I2C、GPIO等IP,采用SMIC40工艺流片。



(一)SoC设计课程,您将学会
  • 高速接口的Verilog设计实现
  • 从图像算法到RTL设计实现
  • MIPI、ISP的Verilog实现与仿真
  • Lint、CDC检查及UVM验证
  • SoC子系统的C驱动仿真
  • 后仿真
仅设计一门课程内容就抵得上其他培训机构的5-6门课程,价格仅其1/6

(二)SoC验证课程,您将学会
  • SoC子系统级的UVM环境搭建
  • SoC子系统级的UVC环境搭建
  • SoC子系统级的VIP环境搭建
  • SoC子系统的DMA SRAM UVM联合验证
  • SoC子系统的UART UVC验证
  • SoC子系统的长包、短包、超长包、毛刺包、包头/包尾错误UVM验证

仅验证一门课程内容就抵得上其他培训机构的3-4门课程,价格仅其1/6


(三)SoC中端课程,您将学会
  • DFT设计(芯片级)
  • Synthesis逻辑综合(芯片级)
  • 低功耗UPF设计、CLP技术
  • formal验证等技术

仅中端一门课程内容就抵得上其他培训机构的4-5门课程价格仅其1/6

(四)SoC后课程,您将学会

  • 低功耗设计

  • 布局布线(低功耗FF flow)
  • StarRC/QRC
  • STA/Tempus
  • 功耗分析
  • DRC/LVS设计

仅后端一门课程内容就抵得上其他培训机构的3-4门课程,价格仅其1/6



课程提供服务器供大家实践!带你从算法、前端、DFT到后端全流程参与SoC项目设计。请联系号主报名!联系微信:135-4139-0811

景芯SoC训练营图像处理的数据通路:



一键式完成C代码编译、仿真、综合、DFT插入、形式验证、布局布线、寄生参数抽取、STA分析、DRC/LVS、后仿真、形式验证、功耗分析等全流程。升级后的芯片设计工程V4.0 flow如下:


SoC一键式执行flow



MIPI DPHY+CSI2解码


数字电路中经典设计:多条通信数据Lane Merging设计实现

数字电路中经典设计:多条通信数据Lane Distribution实现




景芯SoC验证架构


景芯SoC全芯片验证架构:


景芯资深老学员告诉我,留学X国的硕士去外企某芯片巨头薪资是20万+美金!折合RMB超过140万,才25岁左右的小伙子!薪资超140万!


小编去看了glassdoor的工资:

1-3经经验的ASIC Engineer的工资报价有212K美刀,20万美刀。

7-9年经验的ASIC Engineer的工资报价有311K美刀,30万美刀。

当然具体薪资也是看每个候选人的水平以及岗位匹配度。

学历、项目经验都是非常重要的,期待着景芯战友们的更多捷报!走出国门,世界更精彩!景芯SoC项目的正能量之大,小编自己都很震撼,小编一定持续打磨,让景芯战友们一起成功!


景芯SoC UPF低功耗设计

全芯片UPF低功耗设计(含DFT设计)


景芯SoC训练营培训项目,低功耗设计前,功耗为27.9mW。

低功耗设计后,功耗为0.285mW,功耗降低98.9%!



电压降检查:


低功耗检查:


芯片的版图设计V1.0


芯片的版图设计V2.0


芯片的版图设计V4.0


低功耗设计的DRC/LVS,芯片顶层的LVS实践价值极高,具有挑战性!业界独一无二的经验分享。




ISP图像处理

  •    dpc - 坏点校正


  •    blc - 黑电平校正 


  •    bnr - 拜耳降噪

  •    dgain - 数字增益 

  •    demosaic - 去马赛克


  •    wb - 白平衡增益 

  •    ccm - 色彩校正矩阵 

  •    csc - 色彩空间转换 (基于整数优化的RGB2YUV转换公式)

  •    gamma - Gamma校正 (对亮度基于查表的Gamma校正)

  •    ee - 边缘增强


  •    stat_ae - 自动曝光统计 

  •    stat_awb - 自动白平衡统计


CNN图像识别


支持手写数字的AI识别:

仿真结果:仿真识别上图7、2、1、0、4、1、4、9



景芯SoC 3.0 ISP:



景芯SoC V3.0 DFT方案:




如果您和小编一样渴求进步,想掌握芯片设计全流程,欢迎加入小编知识星球,疯狂成长,一起进步!早日成为芯片大佬!


景芯学员们,小编十分感谢你们对景芯的肯定、信任和支持,你们的鼓励让小编十分感激,小编一定更努力精心打磨景芯SoC实战课,我承诺,一定要做到零差评,让大家无论资深还是资浅都能从景芯训练营获得成长!




最近学员纷纷咨询小编offer选择的问题,看到大家通过景芯培训提升后拿到心仪的offer了,非常开心,祝贺大家都拿到心仪offer了!


另外,小编的一个景芯VIP学员,成都某985,硕士7年经验,之前通过景芯培训提升后拿到心仪的offer了,这3个offer我看了都眼红!上次发起了投票,今天公布下结果。先来看下三个offer情况:


1、 某GPU公司,月薪5.8w,年终4个月合计23.2万,年薪92.8万,岗位是SoC前端设计,公积金12%;

2、多媒体SOC厂商JC,月薪6.5w,年终奖2个月合计13万,年薪91万,岗位是SoC芯片设计工程师,公积金12%;

3、 国企X微电子,月薪5.5W,年终奖4个月合计22万,年薪88万,担任数字ic设计工程师,主要从事SOC芯片设计,公积金10%


这里补充发布次大家的投票结果公布:


从结果可以看出,市场行情不好,大家都看好国企军工的稳定性了,GPU仍然是技术首选,虽然GPU公司都在厮杀,但是仍有前景,但是IPC SOC反而得票最低,内卷同时没有太大增量市场。


另外,景芯资深老学员告诉我,留学X国的硕士去外企某芯片巨头薪资是20万+美金!折合RMB超过140万,才25岁左右的小伙子!薪资超140万!努力学习技术吧 骚年。



全栈芯片工程师
十多年SoC、MCU、ISP、CIS芯片设计经验!为客户提供优质的design service!研究生毕业于电子科大,曾就职海思,后加入创业公司任芯片设计经理,创办了景芯SoC全流程芯片设计培训营!
 最新文章