算法基于verilog HDL语言描述:
(1)第一个时钟周期,数据全比较程序
(2)第二个时钟周期,比较值累加
(3)第三个时钟周期,把输入值赋给其对应的排序空间
(4)第四个时钟周期,把排序结果输出
(5)第五个时钟周期,把排序角标输出
source code
`timescale 1ns/1ps
module sort
#(
parameter DATA_WIDTH =8
)
(
input clk,
input rst_n,
input start,
input [DATA_WIDTH-1:0] in0,
input [DATA_WIDTH-1:0] in1,
input [DATA_WIDTH-1:0] in2,
input [DATA_WIDTH-1:0] in3,
input [DATA_WIDTH-1:0] in4,
input [DATA_WIDTH-1:0] in5,
input [DATA_WIDTH-1:0] in6,
output reg [2:0] id0,
output reg [2:0] id1,
output reg [2:0] id2,
output reg [2:0] id3,
output reg [2:0] id4,
output reg [2:0] id5,
output reg [2:0] id6
);
reg add_start;
reg assignm_start;
reg out_start;
reg index_start;
reg complete;
reg [5:0] a,b,c,d,e,f,g;
reg [2:0] tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6;
reg [DATA_WIDTH-1:0] out0,out1,out2,out3,out4,out5,out6;
reg [DATA_WIDTH-1:0] out_tmp [6:0];
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
a <= 6'b000_000;
b <= 6'b000_000;
c <= 6'b000_000;
d <= 6'b000_000;
e <= 6'b000_000;
f <= 6'b000_000;
g <= 6'b000_000;
add_start <= 0;
end
else if(start)
begin
if(in0 <= in1) a[0] <= 1'b1; else a[0] <= 1'b0;
if(in0 <= in2) a[1] <= 1'b1; else a[1] <= 1'b0;
if(in0 <= in3) a[2] <= 1'b1; else a[2] <= 1'b0;
if(in0 <= in4) a[3] <= 1'b1; else a[3] <= 1'b0;
if(in0 <= in5) a[4] <= 1'b1; else a[4] <= 1'b0;
if(in0 <= in6) a[5] <= 1'b1; else a[5] <= 1'b0;
if(in1 < in0) b[0] <= 1'b1; else b[0] <= 1'b0;
if(in1 <= in2) b[1] <= 1'b1; else b[1] <= 1'b0;
if(in1 <= in3) b[2] <= 1'b1; else b[2] <= 1'b0;
if(in1 <= in4) b[3] <= 1'b1; else b[3] <= 1'b0;
if(in1 <= in5) b[4] <= 1'b1; else b[4] <= 1'b0;
if(in1 <= in6) b[5] <= 1'b1; else b[5] <= 1'b0;
if(in2 < in0) c[0] <= 1'b1; else c[0] <= 1'b0;
if(in2 < in1) c[1] <= 1'b1; else c[1] <= 1'b0;
if(in2 <= in3) c[2] <= 1'b1; else c[2] <= 1'b0;
if(in2 <= in4) c[3] <= 1'b1; else c[3] <= 1'b0;
if(in2 <= in5) c[4] <= 1'b1; else c[4] <= 1'b0;
if(in2 <= in6) c[5] <= 1'b1; else c[5] <= 1'b0;
if(in3 < in0) d[0] <= 1'b1; else d[0] <= 1'b0;
if(in3 < in1) d[1] <= 1'b1; else d[1] <= 1'b0;
if(in3 < in2) d[2] <= 1'b1; else d[2] <= 1'b0;
if(in3 <= in4) d[3] <= 1'b1; else d[3] <= 1'b0;
if(in3 <= in5) d[4] <= 1'b1; else d[4] <= 1'b0;
if(in3 <= in6) d[5] <= 1'b1; else d[5] <= 1'b0;
if(in4 < in0) e[0] <= 1'b1; else e[0] <= 1'b0;
if(in4 < in1) e[1] <= 1'b1; else e[1] <= 1'b0;
if(in4 < in2) e[2] <= 1'b1; else e[2] <= 1'b0;
if(in4 < in3) e[3] <= 1'b1; else e[3] <= 1'b0;
if(in4 <= in5) e[4] <= 1'b1; else e[4] <= 1'b0;
if(in4 <= in6) e[5] <= 1'b1; else e[5] <= 1'b0;
if(in5 < in0) f[0] <= 1'b1; else f[0] <= 1'b0;
if(in5 < in1) f[1] <= 1'b1; else f[1] <= 1'b0;
if(in5 < in2) f[2] <= 1'b1; else f[2] <= 1'b0;
if(in5 < in3) f[3] <= 1'b1; else f[3] <= 1'b0;
if(in5 < in4) f[4] <= 1'b1; else f[4] <= 1'b0;
if(in5 <= in6) f[5] <= 1'b1; else f[5] <= 1'b0;
if(in6 < in0) g[0] <= 1'b1; else g[0] <= 1'b0;
if(in6 < in1) g[1] <= 1'b1; else g[1] <= 1'b0;
if(in6 < in2) g[2] <= 1'b1; else g[2] <= 1'b0;
if(in6 < in3) g[3] <= 1'b1; else g[3] <= 1'b0;
if(in6 < in4) g[4] <= 1'b1; else g[4] <= 1'b0;
if(in6 < in5) g[5] <= 1'b1; else g[5] <= 1'b0;
add_start <= 1; //start add
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
tmp0 <= 3'b000;
tmp1 <= 3'b000;
tmp2 <= 3'b000;
tmp3 <= 3'b000;
tmp4 <= 3'b000;
tmp5 <= 3'b000;
tmp6 <= 3'b000;
assignm_start <= 1'b0;
end
else if(add_start)
begin
tmp0 <= a[0] + a[1] + a[2] + a[3] + a[4] + a[5];
tmp1 <= b[0] + b[1] + b[2] + b[3] + b[4] + b[5];
tmp2 <= c[0] + c[1] + c[2] + c[3] + c[4] + c[5];
tmp3 <= d[0] + d[1] + d[2] + d[3] + d[4] + d[5];
tmp4 <= e[0] + e[1] + e[2] + e[3] + e[4] + e[5];
tmp5 <= f[0] + f[1] + f[2] + f[3] + f[4] + f[5];
tmp6 <= g[0] + g[1] + g[2] + g[3] + g[4] + g[5];
assignm_start <= 1'b1;
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
out_tmp[0] <= 'd0;
out_tmp[1] <= 'd0;
out_tmp[2] <= 'd0;
out_tmp[3] <= 'd0;
out_tmp[4] <= 'd0;
out_tmp[5] <= 'd0;
out_tmp[6] <= 'd0;
out_start <= 1'b0;
end
else if(assignm_start)
begin
out_tmp[tmp0] <= in0;
out_tmp[tmp1] <= in1;
out_tmp[tmp2] <= in2;
out_tmp[tmp3] <= in3;
out_tmp[tmp4] <= in4;
out_tmp[tmp5] <= in5;
out_tmp[tmp6] <= in6;
out_start <= 1'b1;
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
out0 <= 'd0;
out1 <= 'd0;
out2 <= 'd0;
out3 <= 'd0;
out4 <= 'd0;
out5 <= 'd0;
out6 <= 'd0;
index_start <= 1'b0;
end
else if(out_start)
begin
out0 <= out_tmp[0];
out1 <= out_tmp[1];
out2 <= out_tmp[2];
out3 <= out_tmp[3];
out4 <= out_tmp[4];
out5 <= out_tmp[5];
out6 <= out_tmp[6];
index_start <= 1'b1;
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
id0 <= 3'd0;
id1 <= 3'd1;
id2 <= 3'd2;
id3 <= 3'd3;
id4 <= 3'd4;
id5 <= 3'd5;
id6 <= 3'd6;
complete <= 1'b0;
end
else if(index_start)
begin
if(out0 == in0) id0 <= 3'd0;
else if(out0 == in1) id0 <= 3'd1;
else if(out0 == in2) id0 <= 3'd2;
else if(out0 == in3) id0 <= 3'd3;
else if(out0 == in4) id0 <= 3'd4;
else if(out0 == in5) id0 <= 3'd5;
else id0 <= 3'd6;
if(out1 == in0) id1 <= 3'd0;
else if(out1 == in1) id1 <= 3'd1;
else if(out1 == in2) id1 <= 3'd2;
else if(out1 == in3) id1 <= 3'd3;
else if(out1 == in4) id1 <= 3'd4;
else if(out1 == in5) id1 <= 3'd5;
else id1 <= 3'd6;
if(out2 == in0) id2 <= 3'd0;
else if(out2 == in1) id2 <= 3'd1;
else if(out2 == in2) id2 <= 3'd2;
else if(out2 == in3) id2 <= 3'd3;
else if(out2 == in4) id2 <= 3'd4;
else if(out2 == in5) id2 <= 3'd5;
else id2 <= 3'd6;
if(out3 == in0) id3 <= 3'd0;
else if(out3 == in1) id3 <= 3'd1;
else if(out3 == in2) id3 <= 3'd2;
else if(out3 == in3) id3 <= 3'd3;
else if(out3 == in4) id3 <= 3'd4;
else if(out3 == in5) id3 <= 3'd5;
else id3 <= 3'd6;
if(out4 == in0) id4 <= 3'd0;
else if(out4 == in1) id4 <= 3'd1;
else if(out4 == in2) id4 <= 3'd2;
else if(out4 == in3) id4 <= 3'd3;
else if(out4 == in4) id4 <= 3'd4;
else if(out4 == in5) id4 <= 3'd5;
else id4 <= 3'd6;
if(out5 == in0) id5 <= 3'd0;
else if(out5 == in1) id5 <= 3'd1;
else if(out5 == in2) id5 <= 3'd2;
else if(out5 == in3) id5 <= 3'd3;
else if(out5 == in4) id5 <= 3'd4;
else if(out5 == in5) id5 <= 3'd5;
else id5 <= 3'd6;
if(out6 == in0) id6 <= 3'd0;
else if(out6 == in1) id6 <= 3'd1;
else if(out6 == in2) id6 <= 3'd2;
else if(out6 == in3) id6 <= 3'd3;
else if(out6 == in4) id6 <= 3'd4;
else if(out6 == in5) id6 <= 3'd5;
else id6 <= 3'd6;
complete <= 1'b1;
end
end
endmodule
仿真平台
`timescale 1ns/1ps
module sort_tb();
parameter DATA_WIDTH =8 ;
reg clk;
reg start;
reg rst_n;
reg [DATA_WIDTH-1:0] in0;
reg [DATA_WIDTH-1:0] in1;
reg [DATA_WIDTH-1:0] in2;
reg [DATA_WIDTH-1:0] in3;
reg [DATA_WIDTH-1:0] in4;
reg [DATA_WIDTH-1:0] in5;
reg [DATA_WIDTH-1:0] in6;
wire [2:0] id0;
wire [2:0] id1;
wire [2:0] id2;
wire [2:0] id3;
wire [2:0] id4;
wire [2:0] id5;
wire [2:0] id6;
parameter t=2;
initial//generate the clock
begin
clk=1'b1;
forever #(t/2) clk=~clk;
end
initial//generate the rst_n
begin
rst_n=1'b1;
#(2*t) rst_n=1'b0;
#(2*t) rst_n=1'b1;
end
initial//generate the input data
begin
#(10*t) start=1'b1;
in0={$random}%256;
in1={$random}%256;
in2={$random}%256;
in3={$random}%256;
in4={$random}%256;
in5={$random}%256;
in6={$random}%256;
end
sort
#(
.DATA_WIDTH(DATA_WIDTH)
)
sort_t
(
.clk(clk),
.rst_n(rst_n),
.start(start),
.in0(in0),
.in1(in1),
.in2(in2),
.in3(in3),
.in4(in4),
.in5(in5),
.in6(in6),
.id0(id0),
.id1(id1),
.id2(id2),
.id3(id3),
.id4(id4),
.id5(id5),
.id6(id6)
);
endmodule