//没改之前错误的代码,下标没对上,i不是从零开始的 reg [DW-1:0] s1_max2[DN/2-1:0]; generate for(i=DN/4;i<DN/2;i=i+1)begin:stage1_second_layer_loop_compare always @(posedge clk) begin if(d[2*i]>d[2*i+1])begin s1_max2[i] <= d[2*i]; end elsebegin s1_max2[i] <= d[2*i+1]; end end end endgenerate //改正之后的代码 reg [DW-1:0] s1_max2[DN/2-1:0]; generate for(i=DN/4;i<DN/2;i=i+1)begin:stage1_second_layer_loop_compare always @(posedge clk) begin if(d[2*i]>d[2*i+1])begin s1_max2[i-DN/4] <= d[2*i]; end elsebegin s1_max2[i-DN/4] <= d[2*i+1]; end end end endgenerate
reg [DW-1:0] s1_max1[DN/2-1:0]; reg [DW-1:0] s1_max2[DN/2-1:0]; // stage 1: first layer generate for(i=0;i<DN/4;i=i+1)begin:stage1_first_layer_loop_compare always @(posedge clk) begin if(d[2*i]>d[2*i+1])begin s1_max1[i] <= d[2*i]; end elsebegin s1_max1[i] <= d[2*i+1]; end end end endgenerate // stage 1: second layer generate for(i=DN/4;i<DN/2;i=i+1)begin:stage1_second_layer_loop_compare always @(posedge clk) begin if(d[2*i]>d[2*i+1])begin s1_max2[i-DN/4] <= d[2*i]; end elsebegin s1_max2[i-DN/4] <= d[2*i+1]; end end end endgenerate
// stage 2: first layer always @(posedge clk) begin if(s1_max1[0]>s1_max1[1])begin max1 <= s1_max1[0]; end elsebegin max1 <= s1_max1[1]; end end // stage 2: second layer always @(posedge clk) begin if(s1_max2[0]>s1_max2[1])begin max2 <= s1_max2[0]; end elsebegin max2 <= s1_max2[1]; end end endmodule
reg [DW-1:0] s1_max1[DN/2-1:0]; reg [DW-1:0] s1_max2[DN/2-1:0]; reg [1:0] s1_addr1[1:0]; reg [1:0] s1_addr2[1:0]; // stage 1: first layer always @(posedge clk) begin if(d[0]>d[1])begin s1_max1[0] <= d[0]; s1_addr1[0] <= 2'b0; end elsebegin s1_max1[0] <= d[1]; s1_addr1[0] <= 2'b01; end end always @(posedge clk) begin if(d[2]>d[3])begin s1_max1[1] <= d[2]; s1_addr1[1] <= 2'b10; end elsebegin s1_max1[1] <= d[3]; s1_addr1[1] <= 2'b11; end end // stage 1: second layer always @(posedge clk) begin if(d[4]>d[5])begin s1_max2[0] <= d[4]; s1_addr2[0] <= 2'b00; end elsebegin s1_max2[0] <= d[5]; s1_addr2[0] <= 2'b01; end end always @(posedge clk) begin if(d[6]>d[7])begin s1_max2[1] <= d[6]; s1_addr2[1] <= 2'b10; end elsebegin s1_max2[1] <= d[7]; s1_addr2[1] <= 2'b11; end end
reg [DW-1:0] tmp_max1 = 8'b0; reg [DW-1:0] tmp_max2 = 8'b0; // stage 2: first layer always @(posedge clk) begin if(s1_max1[0]>s1_max1[1])begin tmp_max1 <= s1_max1[0]; addr1 <= s1_addr1[0]; end elsebegin tmp_max1 <= s1_max1[1]; addr1 <= s1_addr1[1]; end end // stage 2: second layer always @(posedge clk) begin if(s1_max2[0]>s1_max2[1])begin tmp_max2 <= s1_max2[0]; addr2 <= s1_addr1[0]; end elsebegin tmp_max2 <= s1_max2[1]; addr2 <= s1_addr1[1]; end end
//reg [7:0] count=8'b0; //after the last comapre always @(posedge clk) begin if(tmp_max1>max1)begin max1 <= tmp_max1; end elsebegin max1 <= max1; end end always @(posedge clk) begin if(tmp_max2>max2)begin max2 <= tmp_max2; end elsebegin max2 <= max2; end end
module get_max#( parameter DW = 8, //data width parameter DN = 8, //data number parameter AW = 5//output addr width )( input clk, input [DN*DW-1 :0] din, outputreg [DW-1:0] max1, outputreg [DW-1:0] max2, outputreg [9:0] addr1, //final output addr1, add the row_index and col_index to it outputreg [9:0] addr2, //final output addr2, add the row_index and col_index to it outputreg [AW-1:0] row_index1, outputreg [AW-1:0] row_index2, outputreg [AW-1:0] col_index1, outputreg [AW-1:0] col_index2 );
//generate assign the input signal wire [DW-1:0] d[DN-1:0]; generate genvar i; for(i=0;i<DN;i=i+1)begin:loop_assign assign d[i] = din[DW*i+DW-1:DW*i]; end endgenerate
//first stage of the comparison tree reg [DW-1:0] s1_max1[DN/2-1:0]; reg [DW-1:0] s1_max2[DN/2-1:0]; reg [1:0] s1_addr1[1:0]; reg [1:0] s1_addr2[1:0]; // stage 1: first layer always @(posedge clk) begin if(d[0]>d[1])begin s1_max1[0] <= d[0]; s1_addr1[0] <= 2'b0; end elsebegin s1_max1[0] <= d[1]; s1_addr1[0] <= 2'b01; end end always @(posedge clk) begin if(d[2]>d[3])begin s1_max1[1] <= d[2]; s1_addr1[1] <= 2'b10; end elsebegin s1_max1[1] <= d[3]; s1_addr1[1] <= 2'b11; end end // stage 1: second layer always @(posedge clk) begin if(d[4]>d[5])begin s1_max2[0] <= d[4]; s1_addr2[0] <= 2'b00; end elsebegin s1_max2[0] <= d[5]; s1_addr2[0] <= 2'b01; end end always @(posedge clk) begin if(d[6]>d[7])begin s1_max2[1] <= d[6]; s1_addr2[1] <= 2'b10; end elsebegin s1_max2[1] <= d[7]; s1_addr2[1] <= 2'b11; end end
//second stage of the comparison tree reg [DW-1:0] tmp_max1 = 8'b0; reg [DW-1:0] tmp_max2 = 8'b0; reg [1:0] tmp_addr1 = 2'b0; reg [1:0] tmp_addr2 = 2'b0; // stage 2: first layer always @(posedge clk) begin if(s1_max1[0]>s1_max1[1])begin tmp_max1 <= s1_max1[0]; tmp_addr1 <= s1_addr1[0]; end elsebegin tmp_max1 <= s1_max1[1]; tmp_addr1 <= s1_addr1[1]; end end // stage 2: second layer always @(posedge clk) begin if(s1_max2[0]>s1_max2[1])begin tmp_max2 <= s1_max2[0]; tmp_addr2 <= s1_addr2[0]; end elsebegin tmp_max2 <= s1_max2[1]; tmp_addr2 <= s1_addr2[1]; end end
// 这个地方的赋值需要在每次使能后都进行一次,由于开始流水比较会有两个周期的延迟 // 因此要把相关记录下标的count信号并不是从1开始,要加上响应的延迟的影响 reg row_clk = 1'b0; // row clk reg [1:0] div = 1'b1; //div clk for row clk reg [AW-1:0] row_count = 5'd23; // row number reg [AW-1:0] col_count = 3'd4; // col number
// generate the col_count for col_index always @(posedge clk) begin:counter if(col_count == 3'd5)begin col_count <= 1'b0; end elsebegin col_count <= col_count + 1'b1; end if(div == 2'd2)begin row_clk <= ~row_clk; //divide the frequency to clk/6 div <= 1'b0; end elsebegin div <= div + 1'b1; end end // generate the row_count for row_index always @(posedge row_clk) begin if(row_count == 5'd23)begin row_count <= 1'b0; end elsebegin row_count <= row_count + 1'b1; end end
//get the max of all, including the addr of max always @(posedge clk) begin if(tmp_max1>max1)begin max1 <= tmp_max1; row_index1 <= (col_count * 3'd4 + tmp_addr1); col_index1 <= row_count; addr1 <= {row_index1[4:0],col_index1[4:0]}; end elsebegin max1 <= max1; addr1 <= addr1; end end always @(posedge clk) begin if(tmp_max2>max2)begin max2 <= tmp_max2; row_index2 <= (col_count * 3'd4 + tmp_addr2); col_index2 <= row_count; addr2 <= {row_index2[4:0],col_index2[4:0]}; end elsebegin max2 <= max2; addr2 <= addr2; end end endmodule