1、控流水输入:o_dout_rdy 为低时,没有新数据进入,流水线中剩余的数据继续运算完成
2、控流水线每一级:用 o_dout_rdy 控制每一级,o_dout_rdy 为低时,每一级的end、data、flag 保持,直到 o_dout_rdy 为高时,再继续流水
din_en = i_din_vld & o_dout_rdy;
reg din_en_d0, din_en_d1, din_en_d2, din_en_d3;
reg [4-1:0] din_d0, din_d1, din_d2, din_d3;
reg din_flag_d0, din_flag_d1, din_flag_d2, din_flag_d3;
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d0 <= 'd0;
din_d0 <= 'd0;
din_flag_d0 <= 'd0;
end
else if(din_en) begin
din_en_d0 <= din_en;
din_d0 <= din;
din_flag_d0 <= din_flag;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d1 <= 'd0;
din_d1 <= 'd0;
din_flag_d1 <= 'd0;
end
else if(din_en_d0) begin
din_en_d1 <= din_en_d0;
din_d1 <= din_d0;
din_flag_d1 <= din_flag_d0;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d2<= 'd0;
din_d2 <= 'd0;
din_flag_d2 <= 'd0;
end
else if(din_en_d1) begin
din_en_d2<= din_en_d1;
din_d2 <= din_d1;
din_flag_d2 <= din_flag_d1;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d3 <= 'd0;
din_d3 <= 'd0;
din_flag_d3<= 'd0;
end
else if(din_en_d2) begin
din_en_d3 <= din_en_d2;
din_d3 <= din_d2;
din_flag_d3 <= din_flag_d2;
end
end
存在问题:
1、若下一级没有握手信号,与 din_en_d3 握手得到有效 enable 信号,即输出 din_en_d3 为高时,数据就有效,就会导致输出数据重复且被标记为有效数据的情况
2、对于标志位 din_flag_d* ,由于没有复位,则可能出现最后输出的 din_flag_d3 一直为高的问题,同上面的错误数据一起输出多个错误的标志位
din_en = i_din_vld & o_dout_rdy;
reg din_en_d0, din_en_d1, din_en_d2, din_en_d3;
reg [4-1:0] din_d0, din_d1, din_d2, din_d3;
reg din_flag_d0, din_flag_d1, din_flag_d2, din_flag_d3;
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d0 <= 'd0;
din_d0 <= 'd0;
din_flag_d0 <= 'd0;
end
else if(din_en) begin
din_en_d0 <= din_en;
din_d0 <= din;
din_flag_d0 <= din_flag;
end
else begin
din_en_d0 <= 'd0;
din_d0 <= 'd0;
din_flag_d0 <= 'd0;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d1 <= 'd0;
din_d1 <= 'd0;
din_flag_d1 <= 'd0;
end
else if(din_en_d0) begin
din_en_d1 <= din_en_d0;
din_d1 <= din_d0;
din_flag_d1 <= din_flag_d0;
end
else begin
din_en_d1 <= 'd0;
din_d1 <= 'd0;
din_flag_d1 <= 'd0;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d2<= 'd0;
din_d2 <= 'd0;
din_flag_d2 <= 'd0;
end
else if(din_en_d1) begin
din_en_d2<= din_en_d1;
din_d2 <= din_d1;
din_flag_d2 <= din_flag_d1;
end
else begin
din_en_d2<= 'd0;
din_d2 <= 'd0;
din_flag_d2 <= 'd0;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d3 <= 'd0;
din_d3 <= 'd0;
din_flag_d3<= 'd0;
end
else if(din_en_d2) begin
din_en_d3 <= din_en_d2;
din_d3 <= din_d2;
din_flag_d3 <= din_flag_d2;
end
else begin
din_en_d3 <= 'd0;
din_d3 <= 'd0;
din_flag_d3<= 'd0;
end
end
可以看到,数据可以不用复位,只复位din_en_d* 和 din_flag_d* 有正确的标志位即可,即
...
else begin
din_en_d* <= 'd0;
din_flag_d* <= 'd0;
end
...
din_en = i_din_vld & o_dout_rdy;
reg din_en_d0, din_en_d1, din_en_d2, din_en_d3;
reg [4-1:0] din_d0, din_d1, din_d2, din_d3;
reg din_flag_d0, din_flag_d1, din_flag_d2, din_flag_d3;
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d0 <= 'd0;
din_d0 <= 'd0;
din_flag_d0 <= 'd0;
end
else if(din_en) begin
din_en_d0 <= din_en;
din_d0 <= din;
din_flag_d0 <= din_flag;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d1 <= 'd0;
din_d1 <= 'd0;
din_flag_d1 <= 'd0;
end
else if(din_en_d0 & o_dout_rdy) begin
din_en_d1 <= din_en_d0;
din_d1 <= din_d0;
din_flag_d1 <= din_flag_d0;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d2<= 'd0;
din_d2 <= 'd0;
din_flag_d2 <= 'd0;
end
else if(din_en_d1 & o_dout_rdy) begin
din_en_d2<= din_en_d1;
din_d2 <= din_d1;
din_flag_d2 <= din_flag_d1;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d3 <= 'd0;
din_d3 <= 'd0;
din_flag_d3<= 'd0;
end
else if(din_en_d2 & o_dout_rdy) begin
din_en_d3 <= din_en_d2;
din_d3 <= din_d2;
din_flag_d3 <= din_flag_d2;
end
end
可以看到,依然存在2.1 的两个问题:
1、若下一级没有握手信号,与 din_en_d3 握手得到有效 enable 信号,即输出 din_en_d3 为高时,数据就有效,就会导致输出数据重复且被标记为有效数据的情况
2、对于标志位 din_flag_d* ,由于没有复位,则可能出现最后输出的 din_flag_d3 一直为高的问题,同上面的错误数据一起输出多个错误的标志位
优点:
1、实现了目标功能:用 o_dout_rdy 控制流水线的每一级
2、在有效数据的数量(5个)范围内,din_flag_d3 & o_dout_rdy 就是输出数据有效的enable 信号
din_en = i_din_vld & o_dout_rdy;
reg din_en_d0, din_en_d1, din_en_d2, din_en_d3;
reg [4-1:0] din_d0, din_d1, din_d2, din_d3;
reg din_flag_d0, din_flag_d1, din_flag_d2, din_flag_d3;
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d0 <= 'd0;
din_d0 <= 'd0;
din_flag_d0 <= 'd0;
end
else if(din_en) begin
din_en_d0 <= din_en;
din_d0 <= din;
din_flag_d0 <= din_flag;
end
else begin
din_en_d0 <= 'd0;
din_d0 <= 'd0;
din_flag_d0 <= 'd0;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d1 <= 'd0;
din_d1 <= 'd0;
din_flag_d1 <= 'd0;
end
else if(din_en_d0) begin
din_en_d1 <= din_en_d0;
din_d1 <= din_d0;
din_flag_d1 <= din_flag_d0;
end
else begin
din_en_d1 <= 'd0;
din_d1 <= 'd0;
din_flag_d1 <= 'd0;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d2<= 'd0;
din_d2 <= 'd0;
din_flag_d2 <= 'd0;
end
else if(din_en_d1) begin
din_en_d2<= din_en_d1;
din_d2 <= din_d1;
din_flag_d2 <= din_flag_d1;
end
else begin
din_en_d2<= 'd0;
din_d2 <= 'd0;
din_flag_d2 <= 'd0;
end
end
always@(posedge i_clk or negedge i_rstn) begin
if(!i_rstn) begin
din_en_d3 <= 'd0;
din_d3 <= 'd0;
din_flag_d3<= 'd0;
end
else if(din_en_d2) begin
din_en_d3 <= din_en_d2;
din_d3 <= din_d2;
din_flag_d3 <= din_flag_d2;
end
else begin
din_en_d3 <= 'd0;
din_d3 <= 'd0;
din_flag_d3<= 'd0;
end
end