verilog 流水线控制

Verilog 流水线控制

1、关键问题、实现方式及其对比

1、控流水输入:o_dout_rdy 为低时,没有新数据进入,流水线中剩余的数据继续运算完成
2、控流水线每一级:用 o_dout_rdy 控制每一级,o_dout_rdy 为低时,每一级的end、data、flag 保持,直到 o_dout_rdy 为高时,再继续流水

2、实现方式

2.1、控流水线输入:根据每一拍的 din_en_d* 打拍,没有最终的 else block

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

控流水线输入+dout_en_d*+no_else
存在问题:
1、若下一级没有握手信号,与 din_en_d3 握手得到有效 enable 信号,即输出 din_en_d3 为高时,数据就有效,就会导致输出数据重复且被标记为有效数据的情况
2、对于标志位 din_flag_d* ,由于没有复位,则可能出现最后输出的 din_flag_d3 一直为高的问题,同上面的错误数据一起输出多个错误的标志位

2.2、控流水线输入:根据每一拍的 din_en_d* 打拍,有最终的 else block

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

控流水线输入+dout_en_d*+else
可以看到,数据可以不用复位,只复位din_en_d* 和 din_flag_d* 有正确的标志位即可,即

...
else begin
		din_en_d* <= 'd0;
		din_flag_d* <= 'd0;
end
...

2.3、控流水线每一级:根据每一拍的 din_en_d* 和 o_dout_rdy 打拍,没有最终的 else block

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

控流水线输入+dout_en_d* & rdy+no_else

可以看到,依然存在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 信号

2.4、控流水线每一级:根据每一拍的 din_en_d* & o_dout_rdy 打拍,有最终的 else block

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

控流水线输入+dout_en_d* & rdy+else
可以看到,功能和数据基本完全错误
原因:else 复位信号后,下一级无法再获取有效信号

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值