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

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

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


审核编辑:刘清

猜您喜欢

还在为复杂的贴片电阻色环头疼吗?还在手动计算电阻值浪费宝贵时间吗?现在,您可以告别这些烦恼!贴片电阻值计算器,一款简单易用、功能强大的免费工具,让您轻松计算贴片...
2025-04-14 15:02:38

贴片电阻小巧玲珑,在电子电路中随处可见。但是,它们上面的数字和字母代表什么意思呢?其实,理解贴片电阻阻值表示方法非常简单。通常,三位数字表示法最常见。例如,「1...
2025-04-14 15:02:32

贴片电阻作为电子电路中重要的基础元件,其质量直接影响电路性能。最新的贴片电阻检验标准更加严格,涵盖了外观、尺寸、电性能、环境适应性等多个方面。外观检验主要关注电...
2024-11-29 10:26:08

电子设备中,同步整流技术被应用于提高电源转换效率。然而,同步整流管在工作时可能会出现尖峰电压过高的问题,这可能导致器件损坏或系统不稳定。同步整流管尖峰电压过高的...
2024-08-21 00:00:00


FPGA(现场可编程门阵列),它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,一般来说比ASIC(专用集成电路)的速度要慢,实现同样的功能比AS...
2019-07-12 15:24:00

LED驱动主要优势有哪些?随着科技的不断进步,LED照明逐渐成为现代照明的主流选择。LED驱动作为其核心组件,具备诸多优势。LED驱动能有效提升光效。通过精准控...
2014-04-09 00:00:00

贴片电阻器,电子产品中的常见元件,你可能每天都在接触它,却不知其真面目。别担心,这篇指南将教你如何轻松识别它们。首先,观察形状和尺寸。贴片电阻器通常呈小巧的长方...
2024-11-26 11:29:19

数字信号处理器(DSP/DSC)在现代电子设备中是非常重要的配件,其规格尺寸因应用领域和设计需求而异。DSP/DSC的封装类型主要包括QFN、BGA和TQFP等...
2013-09-14 00:00:00

识别贴片电阻好坏,可以从以下几个方面入手:外观检查: 好的贴片电阻表面光滑,无裂纹、缺损或变色。印刷清晰,阻值标识完整。引脚平整,无弯曲或氧化。阻值测量: 使用...
2024-11-26 11:29:50