此处设计的是三级流水线,此处在进行复现的过程中吃了点小亏,就是没有看流水线的介绍直接写代码,导致代码的理解不太深。最后补看了书本但是现在依然有地方不明白。
    首先是防止阻塞的策略:
    此处采用的方法是:就某级流水线而言,它会向后一级发出一个“下一时刻有东西传给你”的请求,同时向前一级发出“下一时刻我可以接收你传来的东西”的反馈,由于流水线串联起来缓缓相扣,因此某一级流水线会同时受到后一级传来的下一时刻是否可以接收东西的反馈信息,以及前一级传来的下一时刻它是否有东西传递过来的请求。热锅某一集流水线当前时刻有东西并想在下一时刻传给后一级流水线 ,但是后一级流水线说下一时刻无法接收传来 的东西,那么该流水级在下一时刻都要保持有当前时刻的东西,即产生阻塞。
    这种设计策略有利于参加CPU添加AXI接口

    1. `timescale 1ns / 1ps
    2. //////////////////////////////////////////////////////////////////////////////////
    3. // Company:
    4. // Engineer:
    5. //
    6. // Create Date: 2021/04/20 16:22:16
    7. // Design Name:
    8. // Module Name: stallable_pipline
    9. // Project Name:
    10. // Target Devices:
    11. // Tool Versions:
    12. // Description:
    13. //
    14. // Dependencies:
    15. //
    16. // Revision:
    17. // Revision 0.01 - File Created
    18. // Additional Comments:
    19. //
    20. //////////////////////////////////////////////////////////////////////////////////
    21. module stallable_pipline#
    22. (
    23. parameter WIDTH=100
    24. )
    25. (
    26. input clk,
    27. input rst,
    28. input validin,
    29. input [WIDTH-1:0] datain,
    30. input out_allow,
    31. output validout,
    32. output [WIDTH-1:0] dataout
    33. );
    34. reg pipe1_valid;
    35. reg [WIDTH-1:0] pipe1_data;
    36. reg pipe2_valid;
    37. reg [WIDTH-1:0] pipe2_data;
    38. reg pipe3_valid;
    39. reg [WIDTH-1:0] pipe3_data;
    40. //pipline stage 1
    41. wire pipe1_allowin;
    42. wire pip1_ready_go;
    43. wire pipe1_to_pipe2_valid;
    44. assign pipe1_ready_go=1;//这里原文是......
    45. assign pipe1_to_pipe2_valid=!pipe1_valid && pipe1_allowin;
    46. assign pipe1_to_pipe2_valid=pipe1_valid && pipe1_ready_go;
    47. always @(posedge clk)begin
    48. if(rst)begin
    49. pipe1_valid<=1'b0;
    50. end
    51. else if(pipe1_allowin)begin
    52. pipe1_valid<=validin;
    53. end
    54. if(validin && pipe1_allowin)begin
    55. pipe1_data<=datain;
    56. end
    57. end
    58. //pipeline stage2
    59. wire pipe2_allowin;
    60. wire pipe2_ready_go;
    61. wire pip32_to_pipe3_valid;
    62. assign pip_ready_go=......
    63. assign pipe2_allowin=!pipe2_valid||pipe2_ready_go&&pipe3_allowin;
    64. assign pipe2_to_pipe3_valid=pipe2_valid&&pipe2_ready_go;
    65. always @(posedge clk)begin
    66. if(rst)begin
    67. pipe2_valid<=1'b0;
    68. end
    69. else if(pipe2_allowin)begin
    70. pipe2_valid<=pipe1_to_pipe2_valid;
    71. end
    72. if(pipe1_to_pipe2_valid && pipe2_allowin)begin
    73. pipe2_data<=pipe1_data;
    74. end
    75. end
    76. //pipeline stage3
    77. wire pipe3_allowin;
    78. wire pipe3_ready_go;
    79. assign pipe3_ready_go=......
    80. assign pipe3_allowin=!pipe3_valid||pipe3——ready_go && out_allow;
    81. always@(posedge clk)begin
    82. if(rst)begin
    83. pipe3_valid<=1'b0;
    84. end
    85. else if(pipe3_allowin)begin
    86. pipe3_valid<=pipe2_to_pipe3_valid;
    87. end
    88. if(pipe2_to_pipe3_valid && pipe3_allowin)begin
    89. pipe3_data<=pipe2_data;
    90. end
    91. end
    92. assign validout = pipe3_valid && pipe3_ready_go;
    93. assign dataout =pipe3_data;
    94. endmodule
    95. endmodule

    此处贴出代码,但是目前这个流水线给人的感觉就是三块流水线的拼合,故不过多的介绍