关于多信号量打拍的方法讨论

文章讨论了在实际工程中如何使用D触发器实现信号打拍,提出CBB(简化版触发器)来简化代码并优化控制和数据信号的处理。通过级联D触发器并根据不同信号的特性(复位与否)进行区分,实现代码的可扩展性。只需调整输入输出信号和参数即可应对信号量变化。
摘要由CSDN通过智能技术生成

在实际工作中,由于时序的原因必须对相关信号打拍(用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

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

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

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值