從這篇開始和知乎專欄里的文章順序有所差異,在專欄里第六到第十篇是關(guān)于異步隨機(jī)驗證的內(nèi)容,而在推送里為了內(nèi)容的前后銜接就放到最后再說。在前面的文章里,我們熟悉了異步邏輯的處理方法:
【芯片設(shè)計】異步電路碎碎念(四) 異步邏輯的處理方法
而后一個順理成章的事情就是練習(xí)寫寫代碼啦。再次匯總下之前提到的異步邏輯同步器結(jié)構(gòu):
1.單比特電平打拍同步器;
2.單比特脈沖打拍同步器;
3.多比特數(shù)據(jù)打拍同步器;
4.多比特電平使能DMUX同步器;
5.多比特脈沖使能握手同步器;
6.異步FIFO;
其中異步FIFO已經(jīng)在前面的專欄中詳細(xì)的寫過代碼了,因此就不在這里重復(fù)。這部分涉及到的代碼位于:
【芯片設(shè)計】FIFO漫談(七)異步FIFO從格雷碼說起
單比特電平打拍同步器單比特打拍同步器的代碼很簡單,不過其中有兩點需要注意:
1.可配置性,主要包括打拍級數(shù)和在源時鐘域是否需要打拍后輸出;
2.專用同步打拍寄存器,實際交付的工程中同步器中的打拍寄存器可能會例化專用的模塊,這是避免被工具優(yōu)化或者做multi-bit,以及在設(shè)置sdc/cdc時方便統(tǒng)一匹配。
不過因為我們只是手撕代碼練習(xí),就不考慮專用打拍寄存器的事了。那么基于上述,手撕代碼如下:
module async_1bit_delay #(
parameter DL = 2,
parameter FF = 1
)( /*AUTOARG*/
// Inputs
i_clk, i_rst_n, i_data, o_clk, o_rst_n, o_data
);
// ----------------------------------------------------------------
// Interface declare
// ----------------------------------------------------------------
input i_clk;
input i_rst_n;
input i_data;
input o_clk;
input o_rst_n;
output o_data;
// ----------------------------------------------------------------
// i_clk pipe
// ----------------------------------------------------------------
wire i_data_in;
generate
if(FF == 0)begin: NO_IN_DFF
assign i_data_in = i_data;
end //if(FF == 0)begin: NO_IN_DFF
else begin: IN_DFF
reg i_data_ff;
always @(posedge i_clk or negedge i_rst_n) begin
if(!i_rst_n)
i_data_ff endgenerate
// ----------------------------------------------------------------
// o_clk pipe
// ----------------------------------------------------------------
reg [DL -1:0]o_data_ff;
integer i;
always @(posedge o_clk or negedge o_rst_n) begin
if(!o_rst_n) begin
o_data_ff 代碼比較簡單所以就不仿真了,反正后面還會反復(fù)調(diào)用這個模塊的。
單比特脈沖打拍同步器
單比特脈沖打拍,核心的功能點就是脈沖展寬,一般需要覆蓋接收域兩拍時鐘(或者三沿原則)。
所以就把時鐘展寬的代碼寫一寫好啦,下面是一種相對比較簡單的脈沖拓展方式:
module async_pulse_widen #(
parameter TIMES = 2
)( /*AUTOARG*/
// Outputs
o_data,
// Inputs
clk, rst_n, i_data
);
// ----------------------------------------------------------------
// Interface declare
// ----------------------------------------------------------------
input clk;
input rst_n;
input i_data;
output o_data;
// ----------------------------------------------------------------
// Wire declare
// ----------------------------------------------------------------
localparam TIMES_W = 8;
// ----------------------------------------------------------------
// AUTO declare
// ----------------------------------------------------------------
/*AUTOOUTPUT*/
/*AUTOINPUT*/
/*AUTOWIRE*/
reg [TIMES_W -1:0]widen_cnt;
wire [TIMES_W -1:0]widen_cnt_d;
wire widen_cnt_en;
assign widen_cnt_en = (i_data && widen_cnt == {TIMES_W{1'b0}}) ||
(widen_cnt == TIMES) ||
(widen_cnt != {TIMES_W{1'b0}}) ;
assign widen_cnt_d = (i_data && widen_cnt == {TIMES_W{1'b0}}) ? widen_cnt + 1'b1 :
(widen_cnt == TIMES) ? 1'b0 :
widen_cnt + 1'b1;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
widen_cnt 這里面的TIMES就是要展寬的倍數(shù),這個代碼的展寬結(jié)果輸出是在脈沖使能的下一拍開始的,如展寬5倍:
同時如果在展寬過程中有下一個脈沖到達(dá),那么是不響應(yīng)的:
多比特數(shù)據(jù)打拍同步器如果多比特數(shù)據(jù)沒有使能信號,也就是說不關(guān)心正確數(shù)值同步過去的時間,只要同步過去就行,或者格雷碼跨異步這種場景,那么可以選擇多比特數(shù)據(jù)打拍同步器。多比特數(shù)據(jù)打拍同步器只需要例化若干單比特打拍同步器就可以了:
module async_nbit_delay #(
parameter DL = 2,
parameter WD = 1,
parameter FF = 1
)( /*AUTOARG*/
// Outputs
o_data,
// Inputs
i_clk, i_rst_n, i_data, o_clk, o_rst_n
);
// ----------------------------------------------------------------
// Interface declare
// ----------------------------------------------------------------
input i_clk;
input i_rst_n;
input [WD -1:0]i_data;
input o_clk;
input o_rst_n;
output[WD -1:0]o_data;
genvar i;
generate
for(i=0; i
系列文章入口——
【芯片設(shè)計】SoC 101(一):緒論 | 【芯片設(shè)計】FIFO漫談(零)從無處不在的FIFO開始說起 | 【芯片設(shè)計】計算機(jī)體系結(jié)構(gòu)(一)虛擬內(nèi)存 | 【芯片設(shè)計】深入理解AMBA總線(零)緒論
| 【芯片設(shè)計】握手協(xié)議的介紹與時序說明 | 【芯片設(shè)計】復(fù)位那些小事 —— 復(fù)位消抖 | 【芯片設(shè)計】快速入門數(shù)字芯片設(shè)計(一)Introduction | 【芯片驗證】UVM源碼計劃(零)下定決心讀源碼前的自測環(huán)節(jié)
| 【芯片設(shè)計】異步電路碎碎念(一) 到底什么是異步電路
| 【芯片設(shè)計】從RTL到GDS(一):Introduction
| 其他文章鏈接——
【芯片驗證】sva_assertion: 15道助力飛升的斷言練習(xí) | 【芯片驗證】可能是RTL定向驗證的巔峰之作 | 【芯片驗證】RTL仿真中X態(tài)行為的傳播 —— 從xprop說起 | 【芯片驗證】年輕人的第一個systemVerilog驗證環(huán)境全工程與解析 |
【芯片設(shè)計】verilog中有符號數(shù)和無符號數(shù)的本質(zhì)探究
| 【芯片設(shè)計】論RTL中always語法的消失術(shù) | 【芯片設(shè)計】代碼即注釋,注釋即代碼 | 【芯片設(shè)計】700行代碼的risc處理器你確實不能要求太多了 |
入職芯片開發(fā)部門后,每天摸魚之外的時間我們要做些什么呢 | 如何計算系統(tǒng)的outstanding 和 burst length? | 芯片搬磚日!け扑缽娖劝Y的關(guān)鍵詞不對齊事件 | 熟人社會里,一群沒有社會價值的局外人 |
|