在vivado上用verilog实现冒泡排序算法

一.要求
设计验证冒泡排序算法。给出设计程序、测试程序、时序仿真结果及分析说明。
二.冒泡排序原理
冒牌排序是将一个数组,按照从小到大进行排列。如下图所示:
假设初始数组元素排列为【8、7、6、5、4、3、2、1】。

经过一次比较排序后为:
在这里插入图片描述
经过一轮排序后为:
在这里插入图片描述
再经过一轮过后为:
在这里插入图片描述
如此,经过几轮过后,就变为:
在这里插入图片描述
这就是冒泡排序的流程。
三.设计代码
module homework3(
clk,rst,load,data_in0,data_in1,data_in2,data_in3,data_in4,
data_in5,data_in6,data_in7,data_out0,data_out1,data_out2,data_out3,data_out4,
data_out5,data_out6,data_out7
);
input clk,rst,load;
input [3:0]data_in0,data_in1,data_in2,data_in3,data_in4,data_in5,data_in6,data_in7;
output [3:0]data_out0,data_out1,data_out2,data_out3,data_out4,data_out5,data_out6,data_out7;
reg [2:0]cnt_i,turn;
reg [3:0]data_fifo[0:7];
parameter s_rst=2’b00,s_load=2’b01,s_sort=2’b10,s_out=2’b11;
reg [1:0]cur_state,next_state;
reg reset,load_data,swap;
always@(posedge clk or negedge rst)
begin
if(!rst)cur_state<=s_rst;
else cur_state<=next_state;
end
always@(posedge clk)
begin
if(reset)
begin
turn<=0;
cnt_i<=0;
end
if(load_data)
begin
data_fifo[0]<=data_in0;
data_fifo[1]<=data_in1;
data_fifo[2]<=data_in2;
data_fifo[3]<=data_in3;
data_fifo[4]<=data_in4;
data_fifo[5]<=data_in5;
data_fifo[6]<=data_in6;
data_fifo[7]<=data_in7;
turn<=7;
cnt_i<=0;
end
if(swap)
begin
if(cnt_i begin
cnt_i<=cnt_i+1;
if(data_fifo[cnt_i+1] begin
data_fifo[cnt_i+1]<=data_fifo[cnt_i];
data_fifo[cnt_i]<=data_fifo[cnt_i+1];
end
end
else
begin
cnt_i<=1;
turn<=turn-1;
if(data_fifo[1] begin
data_fifo[1]<=data_fifo[0];
data_fifo[0]<=data_fifo[1];
end
end
end
end
always@(cnt_i,cur_state,turn,load)
begin
next_state<=s_rst;
case(cur_state)
s_rst:begin
next_state<=s_load;
reset<=1;
end
s_load:begin
reset<=0;
if(load)
begin
next_state<=s_sort;
load_data<=1;
end
else next_state<=s_load;
end
s_sort:begin
swap<=1;
load_data<=0;
if(turn== 1 && cnt_i==1) next_state<=s_out;
else next_state<=s_sort;
end
s_out:begin
swap<=0;
next_state<=s_load;
end
default:begin
next_state<=s_rst;
end
endcase
end
assign data_out0=data_fifo[0];
assign data_out1=data_fifo[1];
assign data_out2=data_fifo[2];
assign data_out3=data_fifo[3];
assign data_out4=data_fifo[4];
assign data_out5=data_fifo[5];
assign data_out6=data_fifo[6];
assign data_out7=data_fifo[7];
endmodule
仿真testbench
`timescale 1ns / 1ns
module simulation(
);
reg clk,rst,load;
reg [3:0]data_in0,data_in1,data_in2,data_in3,data_in4,data_in5,data_in6,data_in7;
wire [3:0]data_out0,data_out1,data_out2,data_out3,data_out4,data_out5,data_out6,data_out7;
initial
begin
#0 rst = 0;
#0 clk = 0;
#0 load=0;
#5 data_in0=8;
data_in1=7;
data_in2=6;
data_in3=5;
data_in4=4;
data_in5=3;
data_in6=2;
data_in7=1;
#11 rst=1;
#120 load=1;
#15 load=0;
#400 data_in0=4’hf;
data_in1=4’he;
data_in2=4’he;
data_in3=4’ha;
data_in4=4’hd;
data_in5=4’hc;
data_in6=4’hb;
data_in7=4’hf;
#10 load=1;
#15 load=0;
#400 $finish;
end
always #5 clk = ~clk;
homework3 test(
.clk(clk),.rst(rst),.load(load) ,
.data_in0(data_in0),.data_in1(data_in1),
.data_in2(data_in2),.data_in3(data_in3),
.data_in4(data_in4),.data_in5(data_in5),
.data_in6(data_in6),.data_in7(data_in7),
.data_out0(data_out0),.data_out1(data_out1),
.data_out2(data_out2),.data_out3(data_out3),
.data_out4(data_out4),.data_out5(data_out5),
.data_out6(data_out6),.data_out7(data_out7)
);
endmodule
四.仿真结果
在vivado上用verilog实现冒泡排序算法_第1张图片
从时序仿真图中可以看出,当输入8个数据为【8、7、6、5、4、3、2、1】时,得到结果是【1、2、3、4、5、6、7、8】,符合冒泡排序;当输入为【f、e、e、a、d、c、b、f】时,得到结果【a、b、c、d、e、e、f、f】符合冒泡排序。
在vivado上用verilog实现冒泡排序算法_第2张图片
同样的,从时序仿真图可以看出,当输入为【3、7、5、2、4、4、9、0】,得到结果是【0、2、3、4、4、5、7、9】;输入为【e、9、3、a、0、f、b、6】,得到结果是【0、3、6、9、a、b、e、f】。
五.代码分析
在vivado上用verilog实现冒泡排序算法_第3张图片
clk:时钟;rst:复位;load:输入数据有效,加载数据;
data:输入8个数,输出8个数;cnt_i:内圈计数器;turn:外圈轮数计数器;
data_fifo:数据缓存;cur_state:当前状态;next_state:下一状态;
reset:复位有效信号;load_data:数据加载有效信号;swap:数据交换有效信号。
在这里插入图片描述
状态清零及转换。

在vivado上用verilog实现冒泡排序算法_第4张图片
当reset信号有效时,进行复位;当load_data信号有效时,进行数据加载,将输入数据放数据fifo,便于操作;当swap信号有效时,进行冒泡排序。冒泡排序思想:cnt_i指向内圈,turn指向外圈(即轮数);turn初始值为7,cnt_i初值为0;首先进行判断比较cnt_i是否与turn值一样(若一样,此时一轮排序结束),值一样,将turn-1,cnt_i赋值为1(不为0是由于cnt_i触发状态转移保持一致);若值不一样,将进行数据大小判断,是否进行交换。
在vivado上用verilog实现冒泡排序算法_第5张图片
状态转移描述,s_rst:清零态,使reset信号有效;s_load:数据态,等待输入load有效使load_data信号有效;s_sort:数据交换状态,使swap信号有效;s_out:冒泡排序结束状态,清除swap信号;最后状态又会回到s_load等待外部将需要排序的数据输入进来排序。

你可能感兴趣的:(课程作业)