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

时间:2025-11-02  作者: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个排好序的数字。

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


审核编辑:刘清

猜您喜欢

安防系统中,监控电源就像人的心脏,源源不断地为摄像头、硬盘录像机等设备提供动力。然而,面对市面上琳琅满目的监控电源,很多用户都会产生疑问:到底应该选择多大功率的...
2023-12-28 00:00:00

电极电阻和电流参数成为电子元器件选型中的关键指标。紫泰荆长作为行业内知名品牌,其电极电阻和电流参数受到关注。本文将围绕“紫泰荆长电极电阻电流参数多少品牌”这一主...
2022-11-05 19:07:01

NTC热敏电阻作为温度检测和控制的关键元件,受到了越来越多的关注。振华科技作为业内知名的电子元器件制造商,其生产的NTC热敏电阻以品质稳定、性能优良。本文将围绕...
2021-10-09 12:28:29

铝壳电阻良好的散热性能和稳定的电气特性应用于各种电路设计中。宇阳(EYANG)作为国内知名的铝壳电阻品牌,高品质的产品质量和合理的电压参数设置,赢得了众多客户的...
2014-01-27 12:38:30

粉尘检测仪是现代工业和环境监测中不可少的重要工具,其主要优势体现在以下几个方面。粉尘检测仪能够实时监测空气中粉尘的浓度,确保工作环境的安全性。通过精准的数据采集...
2015-12-22 00:00:00

电信接口IC是专门用于电信设备中的集成电路,主要负责信号的传输、接收和处理。作为电信系统的核心组件,是连接网络与用户设备的重要配件。电信接口IC可以支持多种通信...
2020-06-05 00:00:00

测水仪是重要的水质检测工具,应用于多个领域。在环境监测方面,测水仪能够实时监测水体的物理和化学指标,如pH值、溶解氧、浊度等,为水质保护提供科学依据。在农业灌溉...
2022-12-09 00:00:00

陶瓷电阻是应用于电子设备中的元器件,良好的热稳定性和耐高温性能受到青睐。陶瓷电阻在使用过程中也有其温度限制,超过这个温度会影响电阻的性能,甚至导致设备故障。那么...
2025-04-14 13:01:43

NTC热敏电阻作为重要的温度传感元件,应用于各种电子设备中。顺络(Sunlord)作为国内知名的电子元器件制造商,其NTC热敏电阻产品以高品质和多样化的规格赢得...
2014-03-31 13:53:40

插件电阻作为电子元器件的重要组成部分,在各种电子设备中是关键配件。格莱尔(GLE)作为知名的插件电阻品牌,很好的性能和优良的品质受到关注。本文将详细介绍格莱尔(...
2018-03-20 13:50:30