开云-【IC技术圈成员文章】异步电路碎碎念(六)手撕打拍同步器

【IC手艺圈成员文章】异步电路碎碎念(六)手撕打拍同步器 时候:2024-12-13 21:24:36 手机看文章

扫描二维码随时随地手机看文章

【芯片设计】异步电路碎碎念(四) 异步逻辑的处置方式

尔后一个瓜熟蒂落的工作就是操练写写代码啦。再次汇总下之条件到的异步逻辑同步器布局:

1.单比特电平打拍同步器;

2.单比特脉冲打拍同步器;

3.多比特数据打拍同步器;

4.多比特电平使能DMUX同步器;

5.多比特脉冲使能握手同步器;

6.异步FIFO;

此中异步FIFO已在前面的专栏中具体的写过代码了,是以就不在这里反复。这部门触及到的代码位在:

【芯片设计】FIFO闲谈(七)异步FIFO从格雷码说起

单比特电平打拍同步器

单比特打拍同步器的代码很简单,不外此中有两点需要留意:

1.可设置装备摆设性,首要包罗打拍级数和在源时钟域是不是需要打拍后输出;

2.专用同步打拍寄放器,现实交付的工程中同步器中的打拍寄放器可能会例化专用的模块,这是避免被东西优化或做multi-bit,和在设置sdc/cdc时便利同一匹配。

不外由于我们只是手撕代码操练,就不斟酌专用打拍寄放器的事了。那末基在上述,手撕代码以下:

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 = 1'b0; else i_data_ff = i_data; end assign i_data_in = i_data_ff; end //else begin: IN_DFF

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 = {DL{1'b0}}; end else begin o_data_ff[0] = i_data_in; for(i=1; i

代码比力简单所以就不仿真了,归正后面还会频频挪用这个模块的。

单比特脉冲打拍同步器

单比特脉冲打拍,焦点的功能点就是脉冲展宽,一般需要笼盖领受域两拍时钟(或三沿原则)。

所以就把时钟展宽的代码写一写好啦,下面是一种相对照较简单的脉冲拓展体例:

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_W{1'b0}}; end else if(widen_cnt_en) begin widen_cnt = widen_cnt_d; end end assign o_data = (widen_cnt != {TIMES_W{1'b0}}); endmodule // Local Variables: // verilog-auto-inst-param-value:t // verilog-library-directories:(".") // verilog-library-extensions:(".v") // End:

这里面的TIMES就是要展宽的倍数,这个代码的展宽成果输出是在脉冲使能的下一拍最先的,如展宽5倍:

同时假如在展宽进程中有下一个脉冲达到,那末是不响应的:

多比特数据打拍同步器

假如多比特数据没有使能旌旗灯号,也就是说不关心准确数值同步曩昔的时候,只要同步曩昔就行,或格雷码跨异步这类场景,那末可以选择多比特数据打拍同步器。多比特数据打拍同步器只需要例化若干单比特打拍同步器便可以了:

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 

欲知详情,请下载word文档 下载文档

上一篇:开云-晶体谐振曲线 下一篇:开云-Python 命令行之旅:深入 click 之子命令篇