当前位置:   article > 正文

关于多信号量打拍的方法讨论_fpga利用eop,sop,vld打节拍

fpga利用eop,sop,vld打节拍

在实际工作中,由于时序的原因必须对相关信号打拍(用D触发器实现)以满足设计要求。

通常思路写法,如下示例代码:

  1. always @ (posedge clk or negedge rst_n) begin : FF_PRO
  2. if(!rst_n) begin
  3. pkt_vld_ff1 <= 1'b0;
  4. pkt_vld_ff2 <= 1'b0;
  5. pkt_sop_ff1 <= 1'b0;
  6. pkt_sop_ff2 <= 1'b0;
  7. pkt_eop_ff1 <= 1'b0;
  8. pkt_eop_ff2 <= 1'b0;
  9. pkt_data_ff1 <= 8'b0;
  10. pkt_data_ff2 <= 8'b0;
  11. end
  12. else begin
  13. pkt_vld_ff1 <= pkt_vld;
  14. pkt_vld_ff2 <= pkt_vld_ff1;
  15. pkt_sop_ff1 <= pkt_sop;
  16. pkt_sop_ff2 <= pkt_sop_ff1;
  17. pkt_eop_ff1 <= pkt_eop;
  18. pkt_eop_ff2 <= pkt_eop_ff1;
  19. pkt_data_ff1 <= pkt_data;
  20. pkt_data_ff2 <= pkt_data_ff1;
  21. end
  22. end

当打拍数增加或者需要打拍的信号量增加,代码长度明显会增加,并且不易扩展。

虽然以上代码看起来很直观,但是这样么有规律的事情什么不做一个CBB呢?

分析以上代码,pkt_vld、pkt_sop、pkt_eop都是控制信号量,信号量打拍需要复位。pkt_data是数据信号量,信号量打拍不需要复位,这样也节省功耗。

带复位的D触发器级联实现:

  1. module SIG_FF_WITH_RST_CBB #(
  2. parameter DATA_WIDTH = 10 ,
  3. parameter FF_NUM = 5 // D触发器级数
  4. )
  5. (
  6. input clk ,
  7. input rst_n ,
  8. input [DATA_WIDTH-1:0] sig_in ,
  9. output reg [DATA_WIDTH-1:0] sig_out
  10. );
  11. reg [DATA_WIDTH-1:0] sig_ff [FF_NUM-2:0] ;
  12. always @ (posedge clk or negedge rst_n) begin : FF_PRO
  13. integer i;
  14. integer j;
  15. if(!rst_n) begin
  16. for(i = 0; i < (FF_NUM-1); i = i + 1) begin
  17. sig_ff[i] <= {DATA_WIDTH{1'b0}};
  18. end
  19. end
  20. else begin
  21. for(j = 0; j < FF_NUM-1; j = j + 1) begin
  22. if (j == 0)
  23. sig_ff[0] <= sig_in;
  24. else
  25. sig_ff[j] <= sig_ff[j-1];
  26. end
  27. end
  28. end
  29. always @ (posedge clk or negedge rst_n) begin
  30. if(!rst_n)
  31. sig_out <= {DATA_WIDTH{1'b0}};
  32. else
  33. sig_out <= sig_ff[FF_NUM-2];
  34. end
  35. endmodule

不带复位的D触发器级联实现:

  1. module SIG_FF_CBB #(
  2. parameter DATA_WIDTH = 10 ,
  3. parameter FF_NUM = 5 // D触发器级数
  4. )
  5. (
  6. input clk ,
  7. input [DATA_WIDTH-1:0] sig_in ,
  8. output wire [DATA_WIDTH-1:0] sig_out
  9. );
  10. reg [DATA_WIDTH-1:0] sig_ff [FF_NUM-1:0] ;
  11. always @ (posedge clk) begin : FF_PRO
  12. integer i;
  13. for(i = 0; i < FF_NUM; i = i + 1) begin
  14. if (i == 0)
  15. sig_ff[0] <= sig_in;
  16. else
  17. sig_ff[i] <= sig_ff[i-1];
  18. end
  19. end
  20. assign sig_out = sig_ff[FF_NUM-1];
  21. endmodule

根据信号量的情况选择,控制信号量代码打拍优化如下:

  1. wire [2:0] sig_ctrl_in;
  2. wire [2:0] sig_ctrl_out;
  3. assgin sig_ctrl_in = {pkt_vld, pkt_sop, pkt_eop};
  4. SIG_FF_WITH_RST_CBB #(
  5. .DATA_WIDTH ( 3 ),
  6. .FF_NUM ( 2 )
  7. )
  8. U_CTRL_SIG_FF_WITH_RST_CBB (
  9. .clk ( clk ), // i
  10. .rst_n ( rst_n ), // i
  11. .sig_in ( sig_ctrl_in ), // i
  12. .sig_out ( sig_ctrl_out ) //o
  13. );
  14. always ( * ) begin
  15. {pkt_vld_ff2, pkt_sop_ff2, pkt_eop_ff2} = sig_ctrl_out;
  16. end

数据信号量代码打拍优化如下:

  1. wire [7:0] sig_data_in;
  2. wire [7:0] sig_data_out;
  3. assgin sig_data_in = {pkt_data};
  4. SIG_FF_CBB #(
  5. .DATA_WIDTH ( 8 ),
  6. .FF_NUM ( 2 )
  7. )
  8. U_DATA_SIG_FF_CBB (
  9. .clk ( clk ), // i
  10. .sig_in ( sig_data_in ), // i
  11. .sig_out ( sig_data_out ) //o
  12. );
  13. always ( * ) begin
  14. {pkt_data_ff2} = sig_data_out;
  15. end

当信号量增加或者打拍数改变,只需要修改输入、输出信号量和参数,容易扩展。

若有不正确的地方,欢迎大家指正。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/676213
推荐阅读
相关标签
  

闽ICP备14008679号