代码写错了,重新完全使用verilog进行归并排序并同时输出原数据的最终排名
时间: 2024-02-05 14:12:43 浏览: 127
归并排序的代码
好的,以下是使用 Verilog 进行归并排序并同时输出原数据的最终排名的代码:
```
module merge_sort(input clk,
input reset,
input [31:0] data_in,
input [31:0] rank_in,
output [31:0] data_out,
output [31:0] rank_out);
parameter N = 8; // 数据个数
parameter LOG_N = 3; // 数据个数的对数
// 存储数组
reg [31:0] data[N];
reg [31:0] rank[N];
// 临时数组
reg [31:0] tmp_data[N];
reg [31:0] tmp_rank[N];
// 内部信号
wire [LOG_N-1:0] stage;
wire [LOG_N-1:0] stage_next;
wire [LOG_N-1:0] i;
wire [LOG_N-1:0] j;
wire [LOG_N-1:0] k;
wire [LOG_N-1:0] k_next;
wire [LOG_N-1:0] m;
wire [LOG_N-1:0] m_next;
wire [LOG_N-1:0] n;
wire [LOG_N-1:0] n_next;
wire [LOG_N-1:0] p;
wire [LOG_N-1:0] p_next;
wire [31:0] x;
wire [31:0] y;
wire [31:0] z;
// 地址计算器
address_calculator ac(clk, reset, stage, stage_next, i, j, k, k_next, m, m_next, n, n_next, p, p_next);
// 数据比较器
data_comparator dc(x, y, z);
// 初始化
initial begin
data[0] = data_in;
rank[0] = rank_in;
end
// 数据输入
always @(posedge clk) begin
if (reset) begin
data[0] <= 0;
rank[0] <= 0;
end else begin
data[0] <= data_in;
rank[0] <= rank_in;
end
end
// 归并排序
always @(posedge clk) begin
// 复制数据到临时数组
for (i = 0; i < N; i = i + 1) begin
tmp_data[i] <= data[i];
tmp_rank[i] <= rank[i];
end
// 归并排序
for (stage = 0; stage < LOG_N; stage = stage + 1) begin
for (i = 0; i < N; i = i + 2**(stage+1)) begin
j = i + 2**stage;
k = i + 2**stage;
k_next = j + 2**stage;
m = i;
m_next = j;
while ((m < j) && (k < k_next)) begin
dc = {tmp_data[m], tmp_data[k]};
if (z == tmp_data[m]) begin
data[i] = tmp_data[m];
rank[i] = tmp_rank[m];
m = m + 1;
end else begin
data[i] = tmp_data[k];
rank[i] = tmp_rank[k];
k = k + 1;
end
i = i + 1;
end
while (m < j) begin
data[i] = tmp_data[m];
rank[i] = tmp_rank[m];
m = m + 1;
i = i + 1;
end
while (k < k_next) begin
data[i] = tmp_data[k];
rank[i] = tmp_rank[k];
k = k + 1;
i = i + 1;
end
end
end
end
// 数据输出
always @(posedge clk) begin
data_out <= data[N-1];
rank_out <= rank[N-1];
end
endmodule
// 地址计算器
module address_calculator(clk,
reset,
stage,
stage_next,
i,
j,
k,
k_next,
m,
m_next,
n,
n_next,
p,
p_next);
input clk;
input reset;
input [3:0] stage;
output [3:0] stage_next;
output [3:0] i;
output [3:0] j;
output [3:0] k;
output [3:0] k_next;
output [3:0] m;
output [3:0] m_next;
output [3:0] n;
output [3:0] n_next;
output [3:0] p;
output [3:0] p_next;
// 内部信号
reg [3:0] _stage;
reg [3:0] _i;
reg [3:0] _j;
reg [3:0] _k;
reg [3:0] _k_next;
reg [3:0] _m;
reg [3:0] _m_next;
reg [3:0] _n;
reg [3:0] _n_next;
reg [3:0] _p;
reg [3:0] _p_next;
// 地址计算器
always @(posedge clk) begin
if (reset) begin
_stage <= 0;
_i <= 0;
_j <= 0;
_k <= 0;
_k_next <= 0;
_m <= 0;
_m_next <= 0;
_n <= 0;
_n_next <= 0;
_p <= 0;
_p_next <= 0;
end else begin
_stage <= stage_next;
_i <= i;
_j <= j;
_k <= k;
_k_next <= k_next;
_m <= m;
_m_next <= m_next;
_n <= n;
_n_next <= n_next;
_p <= p;
_p_next <= p_next;
end
end
// 地址计算
always @(*) begin
stage_next = _stage;
i = _i;
j = _j;
k = _k;
k_next = _k_next;
m = _m;
m_next = _m_next;
n = _n;
n_next = _n_next;
p = _p;
p_next = _p_next;
case (_stage)
0: begin
i = 0;
j = 1;
k = 2;
k_next = 3;
end
1: begin
i = ((_p & 4) << 1) | (_p & 3);
j = i + 1;
k = ((_p & 4) << 1) | ((_p & 3) + 2);
k_next = k + 1;
end
2: begin
m = ((_p & 2) << 2) | (_p & 1);
m_next = m + 1;
n = ((_p & 2) << 2) | ((_p & 1) + 2);
n_next = n + 1;
i = ((_p & 4) << 1) | ((_p & 2) << 1) | (_p & 1);
j = i + 2;
k = ((_p & 4) << 1) | ((_p & 2) << 1) | ((_p & 1) + 2);
k_next = k + 2;
p_next = _p + 1;
end
endcase
end
endmodule
// 数据比较器
module data_comparator(x, y, z);
input [31:0] x;
input [31:0] y;
output [31:0] z;
// 内部信号
wire less_than;
// 数据比较
assign less_than = (x < y);
// 结果输出
assign z = less_than ? x : y;
endmodule
```
这里我们使用了一个地址计算器和一个数据比较器,其中地址计算器用于计算归并排序中的各个地址,数据比较器用于比较两个数据的大小并输出较小的那个数据。同时,我们也加入了 `data_in` 和 `rank_in` 作为输入,以便在排序时可以同时输出原数据的最终排名。
阅读全文