1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-02-25 08:09:51 +00:00
Files
Gehstock.Mist_FPGA/Nintendo - Gameboy_Mist/rtl/sprite_sort.sv
Gehstock d30b32c853 Init
2018-01-22 11:35:05 +01:00

101 lines
2.8 KiB
Systemverilog

//
// sprite_sort.v
//
// Gameboy for the MIST board https://github.com/mist-devel
//
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
module sprite_sort #(
parameter WIDTH = 40
)(
// system signals
input clk,
input load,
// sort
input [8*WIDTH-1:0] x,
output [6*WIDTH-1:0] idx
);
wire [7:0] in [WIDTH-1:0];
generate
genvar i;
// map 1d input array onto 2d work array
// and 2d result array into 1d output array
for(i=0;i<WIDTH;i=i+1) begin : input_map
assign in[i] = x[(8*i)+7:8*i];
assign idx[(6*i)+5:6*i] = index[i];
end
endgenerate
reg [5:0] index [WIDTH-1:0];
reg [7:0] values [WIDTH-1:0];
wire [WIDTH/2-1:0] swap0;
wire [7:0] int_val [WIDTH-1:0];
wire [5:0] int_idx [WIDTH-1:0];
wire [WIDTH/2-2:0] swap1;
wire [7:0] sort_val [WIDTH-1:0];
wire [5:0] sort_idx [WIDTH-1:0];
// sorting takes 10 clock cycles
reg [3:0] cnt;
always @(posedge clk) begin
if(load) cnt <= 4'd0;
if(cnt != 10) cnt <= cnt + 4'd1;
end
generate
// 1st stage
for(i=0;i<WIDTH/2;i=i+1) begin : stage1
assign swap0[i] = values[2*i+0] > values[2*i+1];
assign int_val[2*i+0] = swap0[i]?values[2*i+1]:values[2*i+0];
assign int_val[2*i+1] = swap0[i]?values[2*i+0]:values[2*i+1];
assign int_idx[2*i+0] = swap0[i]?index[2*i+1]:index[2*i+0];
assign int_idx[2*i+1] = swap0[i]?index[2*i+0]:index[2*i+1];
end
// 2nd stage
assign sort_val[0] = int_val[0];
assign sort_idx[0] = int_idx[0];
assign sort_val[WIDTH-1] = int_val[WIDTH-1];
assign sort_idx[WIDTH-1] = int_idx[WIDTH-1];
for(i=0;i<WIDTH/2-1;i=i+1) begin : stage4
assign swap1[i] = int_val[2*i+1] > int_val[2*i+2];
assign sort_val[2*i+1] = swap1[i]?int_val[2*i+2]:int_val[2*i+1];
assign sort_val[2*i+2] = swap1[i]?int_val[2*i+1]:int_val[2*i+2];
assign sort_idx[2*i+1] = swap1[i]?int_idx[2*i+2]:int_idx[2*i+1];
assign sort_idx[2*i+2] = swap1[i]?int_idx[2*i+1]:int_idx[2*i+2];
end
for(i=0;i<WIDTH;i=i+1) begin : advance
always @(posedge clk) begin
if(load) begin
values[i] <= in[i];
index[i] <= i;
end else begin
values[i] <= sort_val[i];
index[i] <= sort_idx[i];
end
end
end
endgenerate
endmodule