赞
踩
在实际工作中,由于时序的原因必须对相关信号打拍(用D触发器实现)以满足设计要求。
通常思路写法,如下示例代码:
- always @ (posedge clk or negedge rst_n) begin : FF_PRO
- if(!rst_n) begin
- pkt_vld_ff1 <= 1'b0;
- pkt_vld_ff2 <= 1'b0;
- pkt_sop_ff1 <= 1'b0;
- pkt_sop_ff2 <= 1'b0;
- pkt_eop_ff1 <= 1'b0;
- pkt_eop_ff2 <= 1'b0;
- pkt_data_ff1 <= 8'b0;
- pkt_data_ff2 <= 8'b0;
- end
- else begin
- pkt_vld_ff1 <= pkt_vld;
- pkt_vld_ff2 <= pkt_vld_ff1;
- pkt_sop_ff1 <= pkt_sop;
- pkt_sop_ff2 <= pkt_sop_ff1;
- pkt_eop_ff1 <= pkt_eop;
- pkt_eop_ff2 <= pkt_eop_ff1;
- pkt_data_ff1 <= pkt_data;
- pkt_data_ff2 <= pkt_data_ff1;
- end
- end
当打拍数增加或者需要打拍的信号量增加,代码长度明显会增加,并且不易扩展。
虽然以上代码看起来很直观,但是这样么有规律的事情什么不做一个CBB呢?
分析以上代码,pkt_vld、pkt_sop、pkt_eop都是控制信号量,信号量打拍需要复位。pkt_data是数据信号量,信号量打拍不需要复位,这样也节省功耗。
带复位的D触发器级联实现:
- module SIG_FF_WITH_RST_CBB #(
- parameter DATA_WIDTH = 10 ,
- parameter FF_NUM = 5 // D触发器级数
- )
- (
- input clk ,
- input rst_n ,
- input [DATA_WIDTH-1:0] sig_in ,
- output reg [DATA_WIDTH-1:0] sig_out
- );
-
- reg [DATA_WIDTH-1:0] sig_ff [FF_NUM-2:0] ;
-
- always @ (posedge clk or negedge rst_n) begin : FF_PRO
- integer i;
- integer j;
- if(!rst_n) begin
- for(i = 0; i < (FF_NUM-1); i = i + 1) begin
- sig_ff[i] <= {DATA_WIDTH{1'b0}};
- end
- end
- else begin
- for(j = 0; j < FF_NUM-1; j = j + 1) begin
- if (j == 0)
- sig_ff[0] <= sig_in;
- else
- sig_ff[j] <= sig_ff[j-1];
- end
- end
- end
-
- always @ (posedge clk or negedge rst_n) begin
- if(!rst_n)
- sig_out <= {DATA_WIDTH{1'b0}};
- else
- sig_out <= sig_ff[FF_NUM-2];
- end
-
- endmodule
不带复位的D触发器级联实现:
- module SIG_FF_CBB #(
- parameter DATA_WIDTH = 10 ,
- parameter FF_NUM = 5 // D触发器级数
- )
- (
- input clk ,
- input [DATA_WIDTH-1:0] sig_in ,
- output wire [DATA_WIDTH-1:0] sig_out
- );
-
- reg [DATA_WIDTH-1:0] sig_ff [FF_NUM-1:0] ;
-
- always @ (posedge clk) begin : FF_PRO
- integer i;
- for(i = 0; i < FF_NUM; i = i + 1) begin
- if (i == 0)
- sig_ff[0] <= sig_in;
- else
- sig_ff[i] <= sig_ff[i-1];
- end
- end
-
- assign sig_out = sig_ff[FF_NUM-1];
-
- endmodule
根据信号量的情况选择,控制信号量代码打拍优化如下:
- wire [2:0] sig_ctrl_in;
- wire [2:0] sig_ctrl_out;
- assgin sig_ctrl_in = {pkt_vld, pkt_sop, pkt_eop};
-
- SIG_FF_WITH_RST_CBB #(
- .DATA_WIDTH ( 3 ),
- .FF_NUM ( 2 )
- )
- U_CTRL_SIG_FF_WITH_RST_CBB (
- .clk ( clk ), // i
- .rst_n ( rst_n ), // i
- .sig_in ( sig_ctrl_in ), // i
- .sig_out ( sig_ctrl_out ) //o
- );
-
- always ( * ) begin
- {pkt_vld_ff2, pkt_sop_ff2, pkt_eop_ff2} = sig_ctrl_out;
- end
数据信号量代码打拍优化如下:
- wire [7:0] sig_data_in;
- wire [7:0] sig_data_out;
-
- assgin sig_data_in = {pkt_data};
-
- SIG_FF_CBB #(
- .DATA_WIDTH ( 8 ),
- .FF_NUM ( 2 )
- )
- U_DATA_SIG_FF_CBB (
- .clk ( clk ), // i
- .sig_in ( sig_data_in ), // i
- .sig_out ( sig_data_out ) //o
- );
-
- always ( * ) begin
- {pkt_data_ff2} = sig_data_out;
- end
当信号量增加或者打拍数改变,只需要修改输入、输出信号量和参数,容易扩展。
若有不正确的地方,欢迎大家指正。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。