1
0
mirror of https://github.com/pConst/basic_verilog.git synced 2025-01-14 06:42:54 +08:00
basic_verilog/slicer_functions.vh
2023-10-25 04:17:06 +03:00

109 lines
2.9 KiB
Systemverilog

//------------------------------------------------------------------------------
// slicer_functions.vh
// published as part of https://github.com/pConst/basic_verilog
// Konstantin Pavlov, pavlovconst@gmail.com
//------------------------------------------------------------------------------
// INFO ------------------------------------------------------------------------
// Arbitrary slice functions for 2D and 3D packed SystemVerilog arrays
// Slices along any array edge, all array sides simultaneously
//
// You can also generalize this aproach to support as many dimentions as needed
//
// This module does NOT consume any FPGA resources though it is absolutely
// synthesizable
//
// Parametrized classes are supported by Vivado, NOT supported by Quartus.
// Please use slicer_2d.sv and slicer_3d.sv conventional modules instead.
//
// Call syntax:
// ============
// assign a[2:1][2:1] = slicer_functions#(
// .I2_HI( 3 ), .I2_LO( 0 ), .I1_HI( 7 ), .I1_LO( 0 ),
// .O2_HI( 2 ), .O2_LO( 1 ), .O1_HI( 2 ), .O1_LO( 1 ) )::slice2d( b[3:0][7:0] );
//
// assign c[2:1][2:1][2:1] = slicer_functions#( .T( my_data_type ),
// .I3_HI( 3 ), .I3_LO( 0 ), .I2_HI( 3 ), .I2_LO( 0 ),
// .I1_HI( 7 ), .I1_LO( 0 ), .O3_HI( 2 ), .O3_LO( 1 ),
// .O2_HI( 2 ), .O2_LO( 1 ), .O1_HI( 2 ), .O1_LO( 1 ) )::slice3d_t( d[3:0][3:0][7:0] );
//
virtual class slicer_functions #( parameter
// input array shape
I3_HI = 3, // most significant size
I3_LO = 0,
I2_HI = 3,
I2_LO = 0,
I1_HI = 7, // least significant size
I1_LO = 0,
// sliced array shape
O3_HI = 2, // most significant size
O3_LO = 1,
O2_HI = 2,
O2_LO = 1,
O1_HI = 2, // least significant size
O1_LO = 1,
type T = int
);
static function [O2_HI:O2_LO][O1_HI:O1_LO] slice2d(
input [I2_HI:I2_LO][I1_HI:I1_LO] in
);
integer i;
for ( i=O2_LO; i<=O2_HI; i++ ) begin
slice2d[i][O1_HI:O1_LO] = in[i][O1_HI:O1_LO];
end //i
endfunction
static function [O3_HI:O3_LO][O2_HI:O2_LO][O1_HI:O1_LO] slice3d(
input [I3_HI:I3_LO][I2_HI:I2_LO][I1_HI:I1_LO] in
);
integer i,j;
for ( i=O3_LO; i<=O3_HI; i++ ) begin
for ( j=O2_LO; j<=O2_HI; j++ ) begin
slice3d[i][j][O1_HI:O1_LO] = in[i][j][O1_HI:O1_LO];
end //j
end //i
endfunction
// Custom data type versions =================================================
static function T [O2_HI:O2_LO][O1_HI:O1_LO] slice2d_t(
input T [I2_HI:I2_LO][I1_HI:I1_LO] in
);
integer i;
for ( i=O2_LO; i<=O2_HI; i++ ) begin
slice2d_t[i][O1_HI:O1_LO] = in[i][O1_HI:O1_LO];
end //i
endfunction
static function T [O3_HI:O3_LO][O2_HI:O2_LO][O1_HI:O1_LO] slice3d_t(
input T [I3_HI:I3_LO][I2_HI:I2_LO][I1_HI:I1_LO] in
);
integer i,j;
for ( i=O3_LO; i<=O3_HI; i++ ) begin
for ( j=O2_LO; j<=O2_HI; j++ ) begin
slice3d_t[i][j][O1_HI:O1_LO] = in[i][j][O1_HI:O1_LO];
end //j
end //i
endfunction
endclass