此处设计的是三级流水线,此处在进行复现的过程中吃了点小亏,就是没有看流水线的介绍直接写代码,导致代码的理解不太深。最后补看了书本但是现在依然有地方不明白。
首先是防止阻塞的策略:
此处采用的方法是:就某级流水线而言,它会向后一级发出一个“下一时刻有东西传给你”的请求,同时向前一级发出“下一时刻我可以接收你传来的东西”的反馈,由于流水线串联起来缓缓相扣,因此某一级流水线会同时受到后一级传来的下一时刻是否可以接收东西的反馈信息,以及前一级传来的下一时刻它是否有东西传递过来的请求。热锅某一集流水线当前时刻有东西并想在下一时刻传给后一级流水线 ,但是后一级流水线说下一时刻无法接收传来 的东西,那么该流水级在下一时刻都要保持有当前时刻的东西,即产生阻塞。
这种设计策略有利于参加CPU添加AXI接口
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2021/04/20 16:22:16
// Design Name:
// Module Name: stallable_pipline
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module stallable_pipline#
(
parameter WIDTH=100
)
(
input clk,
input rst,
input validin,
input [WIDTH-1:0] datain,
input out_allow,
output validout,
output [WIDTH-1:0] dataout
);
reg pipe1_valid;
reg [WIDTH-1:0] pipe1_data;
reg pipe2_valid;
reg [WIDTH-1:0] pipe2_data;
reg pipe3_valid;
reg [WIDTH-1:0] pipe3_data;
//pipline stage 1
wire pipe1_allowin;
wire pip1_ready_go;
wire pipe1_to_pipe2_valid;
assign pipe1_ready_go=1;//这里原文是......
assign pipe1_to_pipe2_valid=!pipe1_valid && pipe1_allowin;
assign pipe1_to_pipe2_valid=pipe1_valid && pipe1_ready_go;
always @(posedge clk)begin
if(rst)begin
pipe1_valid<=1'b0;
end
else if(pipe1_allowin)begin
pipe1_valid<=validin;
end
if(validin && pipe1_allowin)begin
pipe1_data<=datain;
end
end
//pipeline stage2
wire pipe2_allowin;
wire pipe2_ready_go;
wire pip32_to_pipe3_valid;
assign pip_ready_go=......
assign pipe2_allowin=!pipe2_valid||pipe2_ready_go&&pipe3_allowin;
assign pipe2_to_pipe3_valid=pipe2_valid&&pipe2_ready_go;
always @(posedge clk)begin
if(rst)begin
pipe2_valid<=1'b0;
end
else if(pipe2_allowin)begin
pipe2_valid<=pipe1_to_pipe2_valid;
end
if(pipe1_to_pipe2_valid && pipe2_allowin)begin
pipe2_data<=pipe1_data;
end
end
//pipeline stage3
wire pipe3_allowin;
wire pipe3_ready_go;
assign pipe3_ready_go=......
assign pipe3_allowin=!pipe3_valid||pipe3——ready_go && out_allow;
always@(posedge clk)begin
if(rst)begin
pipe3_valid<=1'b0;
end
else if(pipe3_allowin)begin
pipe3_valid<=pipe2_to_pipe3_valid;
end
if(pipe2_to_pipe3_valid && pipe3_allowin)begin
pipe3_data<=pipe2_data;
end
end
assign validout = pipe3_valid && pipe3_ready_go;
assign dataout =pipe3_data;
endmodule
endmodule
此处贴出代码,但是目前这个流水线给人的感觉就是三块流水线的拼合,故不过多的介绍