diff --git a/arbitrary_slicer_2d.sv b/slicer_2d.sv similarity index 78% rename from arbitrary_slicer_2d.sv rename to slicer_2d.sv index 36e0d1d..cc5c66a 100644 --- a/arbitrary_slicer_2d.sv +++ b/slicer_2d.sv @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// arbitrary_slicer_2d.sv +// slicer_2d.sv // Konstantin Pavlov, pavlovconst@gmail.com //------------------------------------------------------------------------------ @@ -16,12 +16,12 @@ /* --- INSTANTIATION TEMPLATE BEGIN --- -arbitrary_slicer_2d #( - .I2_HI( 3 ), .I2_LO( 0 ), - .I1_HI( 7 ), .I1_LO( 0 ), +slicer_2d #( + .I2_HI( 3 ), .I2_LO( 0 ), + .I1_HI( 7 ), .I1_LO( 0 ), - .O2_HI( 2 ), .O2_LO( 1 ), - .O1_HI( 2 ), .O1_LO( 1 ) + .O2_HI( 2 ), .O2_LO( 1 ), + .O1_HI( 2 ), .O1_LO( 1 ) ) S1 ( .in ( a[3:0][7:0] ), .out( b[2:1][2:1] ) @@ -30,7 +30,7 @@ arbitrary_slicer_2d #( --- INSTANTIATION TEMPLATE END ---*/ -module arbitrary_slicer_3d #( parameter +module slicer_2d #( parameter // input array shape I2_HI = 3, // most significant size @@ -54,9 +54,9 @@ module arbitrary_slicer_3d #( parameter integer i; always_comb begin - for ( i=O2_LO; i<=O2_HI; i++ ) begin - out[i][O1_HI:O1_LO] = in[i][O1_HI:O1_LO]; - end + for ( i=O2_LO; i<=O2_HI; i++ ) begin + out[i][O1_HI:O1_LO] = in[i][O1_HI:O1_LO]; + end end diff --git a/arbitrary_slicer_3d.sv b/slicer_3d.sv similarity index 81% rename from arbitrary_slicer_3d.sv rename to slicer_3d.sv index cdde634..2b7a4b2 100644 --- a/arbitrary_slicer_3d.sv +++ b/slicer_3d.sv @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// arbitrary_slicer_3d.sv +// slicer_3d.sv // Konstantin Pavlov, pavlovconst@gmail.com //------------------------------------------------------------------------------ @@ -16,14 +16,14 @@ /* --- INSTANTIATION TEMPLATE BEGIN --- -arbitrary_slicer_3d #( - .I3_HI( 3 ), .I3_LO( 0 ), - .I2_HI( 3 ), .I2_LO( 0 ), - .I1_HI( 7 ), .I1_LO( 0 ), +slicer_3d #( + .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 ) + .O3_HI( 2 ), .O3_LO( 1 ), + .O2_HI( 2 ), .O2_LO( 1 ), + .O1_HI( 2 ), .O1_LO( 1 ) ) S1 ( .in ( a[3:0][3:0][7:0] ), .out( b[2:1][2:1][2:1] ) @@ -32,7 +32,7 @@ arbitrary_slicer_3d #( --- INSTANTIATION TEMPLATE END ---*/ -module arbitrary_slicer_3d #( parameter +module slicer_3d #( parameter // input array shape I3_HI = 3, // most significant size @@ -45,7 +45,7 @@ module arbitrary_slicer_3d #( parameter I1_LO = 0, // sliced array shape - O3_HI = 2, // most significant size + O3_HI = 2, // most significant size O3_LO = 1, O2_HI = 2, diff --git a/slicer_functions.vh b/slicer_functions.vh new file mode 100644 index 0000000..5b231b6 --- /dev/null +++ b/slicer_functions.vh @@ -0,0 +1,80 @@ +//------------------------------------------------------------------------------ +// 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#( +// .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( 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 +); + + + 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 + +endclass +