FPGA排序-冒泡排序(Verilog版)介绍

时间:2025-11-01  作者:Diven  阅读:0

在之前的推文中介绍了冒泡排序的实现,但是分享的代码使用的是SpinalHDL,最近有好多小伙伴后台私信问有没有Verilog版的代码。今天就给大家贴出来,具体原理参考FPGA排序--冒泡排序这篇之前的文章。

FPGA排序-冒泡排序(Verilog版)介绍

仍然以8个8bit的数为例来介绍冒泡排序,因此数据的输入和输出位宽均为64bit(8*8bit),使用valid信号来标识数据有效,整个实现采用流水线的方式。

 

`timescale 1ns / 1psModule bubble( input clk , input rst , input [63:0] data_in , input data_in_valid , output [63:0] data_out , output data_out_valid); reg [ 3:0] data_in_valid_ff; reg [63:0] data_in_ff[3:0] ; reg v[7:0][7:0] ; reg [ 1:0] sum_1[7:0][3:0] ; reg [ 2:0] sum_2[7:0][1:0] ; reg [ 3:0] sum_3[7:0] ; reg [7:0] data_out_temp[7:0] ; reg data_out_valid_temp; genvar i; genvar j; always @(posedge clk ) begin if(rst == 1'b1)begin data_in_valid_ff <= 4'b0; end else begin data_in_valid_ff <= {data_in_valid_ff[2:0], data_in_valid}; end end always @(posedge clk ) begin data_in_ff[0] <= data_in; end generate for ( i = 0; i < 3 ; i = i + 1 ) begin : LOOP_DATA_IN always @(posedge clk ) begin data_in_ff[i+1] <= data_in_ff[i]; end end endgenerate generate for ( i = 0 ; i < 8 ; i = i + 1 ) begin : LOOP_V_I for ( j = i ; j < 8 ; j = j + 1) begin : LOOP_V_J always @(posedge clk ) begin if(data_in_valid == 1'b1)begin v[i][j] <= data_in[i*8 +: 8] >= data_in[j*8 +: 8]; v[j][i] <= data_in[i*8 +: 8] < data_in[j*8 +: 8]; end end end end endgenerate generate for ( i = 0 ; i < 8 ; i = i + 1 ) begin : LOOP_SUM_1_I for ( j = 0 ; j < 4 ; j = j + 1) begin : LOOP_SUM_1_J always @(posedge clk ) begin if(data_in_valid_ff[0] == 1'b1)begin sum_1[i][j] <= v[i][j*2] + v[i][j*2 + 1]; end end end end endgenerate generate for ( i = 0 ; i < 8 ; i = i + 1 ) begin : LOOP_SUM_2_I for ( j = 0 ; j < 2 ; j = j + 1) begin : LOOP_SUM_2_J always @(posedge clk ) begin if(data_in_valid_ff[1] == 1'b1)begin sum_2[i][j] <= sum_1[i][j*2] + sum_1[i][j*2 + 1]; end end end end endgenerate generate for ( i = 0 ; i < 8 ; i = i + 1 ) begin : LOOP_SUM_3_I always @(posedge clk ) begin if(data_in_valid_ff[2] == 1'b1)begin sum_3[i] <= sum_2[i][0] + sum_2[i][1]; end end end endgenerate always @(posedge clk ) begin : LOOP_DATA_OUT_TEMP_CLK integer k; for ( k = 0; k < 8; k = k + 1) begin : LOOP_DATA_OUT_TEMP if(data_in_valid_ff[3] == 1'b1)begin data_out_temp[sum_3[k]] <= data_in_ff[3][k*8 +: 8]; data_out_valid_temp <= 1'b1; end else begin data_out_temp[sum_3[k]] <= 8'd0; data_out_valid_temp <= 1'b0; end end end generate for ( i = 0 ; i < 8 ; i = i + 1) begin : LOOP_DATA_OUT assign data_out[i*8 +: 8] = data_out_temp[i] ; assign data_out_valid = data_out_valid_temp; end endgenerateendModule

在代码中用了大量的生成语句,这样可以降低我们的代码量,这些生成语句帮我们生成了大量的重复性电路,我们并不需要有什么担心。

仿真代码:

 

`timescale 1ns / 1psmodule tb_bubble( ); reg clk; reg rst; reg [7:0] data_in_0; reg [7:0] data_in_1; reg [7:0] data_in_2; reg [7:0] data_in_3; reg [7:0] data_in_4; reg [7:0] data_in_5; reg [7:0] data_in_6; reg [7:0] data_in_7; wire [63:0] data_in; reg data_in_valid; wire [63:0] data_out; wire data_out_valid; initial begin clk = 1'b0; rst = 1'b1; #50 rst = 1'b0; end always #5 clk = !clk; always @(posedge clk ) begin if(rst == 1'b1)begin data_in_0 <= 8'd0; data_in_1 <= 8'd0; data_in_2 <= 8'd0; data_in_3 <= 8'd0; data_in_4 <= 8'd0; data_in_5 <= 8'd0; data_in_6 <= 8'd0; data_in_7 <= 8'd0; data_in_valid <= 1'b0; end else begin data_in_0 <= {$random} % 255; data_in_1 <= {$random} % 255; data_in_2 <= {$random} % 255; data_in_3 <= {$random} % 255; data_in_4 <= {$random} % 255; data_in_5 <= {$random} % 255; data_in_6 <= {$random} % 255; data_in_7 <= {$random} % 255; data_in_valid <= 1'b1; end end assign data_in = {data_in_0, data_in_1, data_in_2, data_in_3, data_in_4, data_in_5, data_in_6, data_in_7}; bubble u_bubble( .clk (clk ), .rst (rst ), .data_in (data_in ), .data_in_valid (data_in_valid ), .data_out (data_out ), .data_out_valid (data_out_valid) );endmodule


仿真结果:

可以看到每个时钟周期输出8个排好序的数字。

消耗的资源如上。如果我们不需要流水输出的话,使用的资源可以进一步进行压缩,这个就看具体的需求了,资源和性能的平衡。


审核编辑:刘清

猜您喜欢

肖特基二极管因其独特的结构和性能,在电子设备中得到了应用。与传统的PN结二极管相比,肖特基二极管具有更低的正向压降、更快的开关速度和更高的效率。许多人在选择二极...
2025-03-29 09:30:02

如今电子设备日益普及的时代,稳定可靠的电源供应很重要。DC-DC开关电源作为一种高效的电压转换器,能够将一个直流电压转换为另一个所需的直流电压,应用于各种电子设...
2024-11-08 00:00:00

电流检测电阻作为关键元件,应用于电源管理、电机控制和电池保护等领域。作为全球知名的电子元器件制造商,VISHAY(威世)高品质和多样化的电阻产品赢得了业界的高度...
2015-05-16 20:51:31

压敏电阻作为重要的电子元件,在电路保护和浪涌抑制中有着着关键作用。ASJ(新加坡)作为知名的压敏电阻品牌,其产品在市场上受到关注。本文将围绕“ASJ(新加坡)压...
2014-11-11 17:26:30

低压差线性稳压器 (LDO) 是一种电子电路,用于将变化的直流电压转换为稳定的低纹波输出电压。与其类型的线性稳压器相比,LDO 可以在输入电压和输出电压之间保持...
2024-08-27 00:00:00

1. Spartan-6系列封装概述  Spartan-6系列具有低成本、省空间的封装形式,能使用户引脚密度最大化。所有Spartan-6 LX器件之间的引...
2018-07-01 10:48:00

电刨作为常见的木工工具,其种类和功能各有不同。在选择电刨时,了解其区别非常重要。电刨根据功率的不同可以分为小功率和大功率两种。小功率电刨适合家庭使用,轻便易操作...
2013-03-03 00:00:00

2010-09-21 00:00:00

塞规是用于检测零件尺寸和形状的工具,应用于机械制造和质量控制中。根据不同的用途和结构,塞规可以分为以下几类。首先是标准塞规,是按照国家或国际标准制造的,主要用于...
2013-07-26 00:00:00

贴片电阻2R7,别看它身材小巧,却是电子电路中不可或缺的重要元件。它代表着2.7欧姆的电阻值,「R」是电阻值的单位符号,这种表示方法在电子领域十分常见。贴片电阻...
2024-11-26 11:30:01