秋招手撕代码:用verilog实现二输入比较器实现排序算法(单周期内实现8个数的排序)
给定8个数,以及若干二输入的比较器(可以将两个输入排序)。要求在单周期内实现8个数的排序,并使用最少的比较器个数。
题目来源于博客园:
https://www.cnblogs.com/lyc-seu/p/13385782.html
根本博客园的这篇博客,先给一个不是最少二输入比较器的版本,后面比较器个数最少的verilog代码。
1、verilog代码及设计思路
除了上面的博客提供的思路外,我再说一下我的代码思路,我是先将写了一个四输入的选择器,再利用四输入的选择器搭建八输入的选择器。
四输入的设计思路如下图所示:
八输入的设计思想如下图所示:
module sort8#(parameter DW=8)(
input [DW-1:0]i_d0,
input [DW-1:0]i_d1,
input [DW-1:0]i_d2,
input [DW-1:0]i_d3,
input [DW-1:0]i_d4,
input [DW-1:0]i_d5,
input [DW-1:0]i_d6,
input [DW-1:0]i_d7,
output reg [DW-1:0]o_d0,//最小
output reg [DW-1:0]o_d1,
output reg [DW-1:0]o_d2,
output reg [DW-1:0]o_d3,
output reg [DW-1:0]o_d4,
output reg [DW-1:0]o_d5,
output reg [DW-1:0]o_d6,
output reg [DW-1:0]o_d7
);
function [DW*2-1:0]max;
input [DW-1:0]data0;
input [DW-1:0]data1;
begin
max=data0<=data1?{data1,data0}:{data0,data1};//左边大
end
endfunction
function [DW*4-1:0]max_4;
input [DW-1:0]d0;
input [DW-1:0]d1;
input [DW-1:0]d2;
input [DW-1:0]d3;
reg [DW-1:0]r0;
reg [DW-1:0]r1;
reg [DW-1:0]r2;
reg [DW-1:0]r3;
reg [DW-1:0]r4;
reg [DW-1:0]r5;
reg [DW-1:0]r6;
reg [DW-1:0]r7;
reg [DW-1:0]r8;
reg [DW-1:0]r9;
begin
{r0,r1}=max(d0,d1);//左大
{r2,r3}=max(d2,d3);
{r4,r5}=max(r0,r2);//r4最大
{r6,r7}=max(r1,r3);//r7最小
{r8,r9}=max(r6,r5);//r8次大,r9次小
max_4={r4,r8,r9,r7};
end
endfunction
//reg [DW*4-1:0]max_4_r;
/* always@(*)
max_4_r=max_4(i_d0,i_d1,i_d2,i_d3);
assign o_d0=max_4_r[7:0];
assign o_d1=max_4_r[15:8];//四输入比较
assign o_d2=max_4_r[23:16];
assign o_d3=max_4_r[31:24]; */
//8输入比较
reg [DW-1:0]m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15,m16,m17,m18,m19;
always@(*)
begin
{m0,m1,m2,m3}=max_4(i_d0,i_d1,i_d2,i_d3);
{m4,m5,m6,m7}=max_4(i_d4,i_d5,i_d6,i_d7);
{m8,m9,m10,m11}=max_4(m0,m1,m4,m5);
{m12,m13,m14,m15}=max_4(m2,m3,m6,m7);
{m16,m17,m18,m19}=max_4(m10,m11,m12,m13);
o_d0=m15;//最小
o_d1=m14;
o_d2=m19;
o_d3=m18;
o_d4=m17;
o_d5=m16;
o_d6=m9;
o_d7=m8;
end
endmodule
2、仿真文件:
module sort8_tst();
reg [8-1:0] i_d0 ;
reg [8-1:0] i_d1 ;
reg [8-1:0] i_d2 ;
reg [8-1:0] i_d3 ;
reg [8-1:0] i_d4 ;
reg [8-1:0] i_d5 ;
reg [8-1:0] i_d6 ;
reg [8-1:0] i_d7 ;
wire [8-1:0]o_d0 ;
wire [8-1:0]o_d1 ;
wire [8-1:0]o_d2 ;
wire [8-1:0]o_d3 ;
wire [8-1:0]o_d4 ;
wire [8-1:0]o_d5 ;
wire [8-1:0]o_d6 ;
wire [8-1:0]o_d7 ;
sort8 U_sort8(
.i_d0(i_d0),
.i_d1(i_d1),
.i_d2(i_d2),
.i_d3(i_d3),
.i_d4(i_d4),
.i_d5(i_d5),
.i_d6(i_d6),
.i_d7(i_d7),
.o_d0(o_d0),
.o_d1(o_d1),
.o_d2(o_d2),
.o_d3(o_d3),
.o_d4(o_d4),
.o_d5(o_d5),
.o_d6(o_d6),
.o_d7(o_d7)
);
initial
begin
i_d0=8'd23;
i_d1=8'd87;
i_d2=8'd3;
i_d3=8'd76;
i_d4=8'd1;
i_d5=8'd2;
i_d6=8'd3;
i_d7=8'd4;
end
endmodule
最少选择器的版本我后续会更新,基本上只要学会使用function,然后知道这个是“搭积木”,能把图形画出来就能写出代码来。如果大家发现代码或者思路有问题,欢迎大家批评指正。