开云-BPO行业整合方案提供者
专业化、科技化、国际化;高标准、广覆盖、全流程
了解更多【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;// ----------------------------------------------------------------欲知详情,请下载word文档 下载文档// 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_DFFendgenerate
// ----------------------------------------------------------------// 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