先是看到一道题是用verilog实现寻找8个数中的最大值,实现后又试着加上寻找次大值和最小值。先说下大概思路,采用流水线方式,8个数据分为4组,每2个数据进行比较,得到最大值和最小值;然后把这四个最大值和四个最小值再分为2组,每组的输入为2个最大值和最小值,输出为4个数据中的最大值、次大值和最小值;最后再把2个中间模块的输出进行比较得到最终的最大值、次大值和最小值。可能描述的不清楚,见下图。
代码如下:
module comp#( parameter DW = 8)( input clk, input rst_n, input [DW-1:0] din1, input [DW-1:0] din2, output reg [DW-1:0] max, output reg [DW-1:0] min);always @ (posedge clk or rst_n) begin if(!rst_n) begin max <= 'd0; min <= 'd0; end else if(din1 >= din2) begin max <= din1; min <= din2; end else begin max <= din2; min <= din1; end end endmodule
module comp2#( parameter DW = 8)( input clk, input rst_n, input [DW-1:0] din1, input [DW-1:0] din2, input [DW-1:0] din3, input [DW-1:0] din4, output reg [DW-1:0] max1, output reg [DW-1:0] max2, output reg [DW-1:0] min);wire [DW-1:0] c1_max;wire [DW-1:0] c1_min;wire [DW-1:0] c2_max;wire [DW-1:0] c2_min;always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin max1 <= 'd0; end else if(c1_max >= c2_max) begin max1 <= c1_max; end else begin max1 <= c2_max; end end always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin max2 <= 'd0; end else if(c1_max >= c2_max) begin if(c1_min >= c2_min) begin max2 <= c1_min; end else begin max2 <= c2_min; end end else begin if(c1_max >= c2_min) begin max2 <= c1_max; end else begin max2 <= c2_min; end end end always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin min <= 'd0; end else if(c1_min >= c2_min) begin min <= c2_min; end else begin min <= c1_min; end end comp#( .DW (DW ))u1_comp( .clk (clk ), .rst_n (rst_n ), .din1 (din1 ), .din2 (din2 ), .max (c1_max ), .min (c1_min ));comp#( .DW (DW ))u2_comp( .clk (clk ), .rst_n (rst_n ), .din1 (din3 ), .din2 (din4 ), .max (c2_max ), .min (c2_min ));endmodule
module comp3#( parameter DW = 8)( input clk, input rst_n, input [DW-1:0] din1, input [DW-1:0] din2, input [DW-1:0] din3, input [DW-1:0] din4, input [DW-1:0] din5, input [DW-1:0] din6, input [DW-1:0] din7, input [DW-1:0] din8, output reg [DW-1:0] max1, output reg [DW-1:0] max2, output reg [DW-1:0] min);wire [DW-1:0] d1_max1;wire [DW-1:0] d1_max2;wire [DW-1:0] d1_min;wire [DW-1:0] d2_max1;wire [DW-1:0] d2_max2;wire [DW-1:0] d2_min;always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin max1 <= 'd0; end else if(d1_max1 >= d2_max1) begin max1 <= d1_max1; end else begin max1 <= d2_max1; end end always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin max2 <= 'd0; end else if(d1_max1 >= d2_max1) begin if(d1_max2 >= d2_max1) begin max2 <= d1_max2; end else begin max2 <= d2_max1; end end else begin if(d1_max1 >= d2_max2) begin max2 <= d1_max1; end else begin max2 <= d2_max2; end end end always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin min <= 'd0; end else if(d1_min >= d2_min) begin min <= d2_min; end else begin min <= d1_min; end end comp2#( .DW (DW ))u1_comp2( .clk (clk ), .rst_n (rst_n ), .din1 (din1 ), .din2 (din2 ), .din3 (din3 ), .din4 (din4 ), .max1 (d1_max1 ), .max2 (d1_max2 ), .min (d1_min ) );comp2#( .DW (DW ))u2_comp2( .clk (clk ), .rst_n (rst_n ), .din1 (din5 ), .din2 (din6 ), .din3 (din7 ), .din4 (din8 ), .max1 (d2_max1 ), .max2 (d2_max2 ), .min (d2_min ) );endmodule
仿真结果如下:
2 4 8
3个时钟周期后得出8个数据中的最大值、次大值和最小值。