Regarding that a declaration of [N] for a SystemVerilog unpacked array dimension implies upto indexing [0:N-1], I noted here that by instead using the hardware-style downto indexing [N-1:0] you can split/merge dimensions more fluidly. For example,

typedef struct{intx, y;} T;moduletest#(N=2,M=3) (outputT A_2D[(2**N)-1:0][(2**M)-1:0] ,outputT A_1D[(2**(N+M))-1:0] );logic[N-1:0] idx_N;logic[M-1:0] idx_M;always_comb beginfor(inti = 0; i < 2**N; i++)beginfor(intj = 0; j < 2**M; j++)beginidx_N = i; idx_M = j; A_2D[idx_N][idx_M] = '{i,j}; A_1D[{idx_N,idx_M}] = '{i,j};assert final(A_2D[idx_N][idx_M] == A_1D[{idx_N,idx_M}]);end end end endmodule:test

But with upto indexing [0:N-1] you’d need to flip the order of dimensions in the indexes, as in

typedef struct{intx, y;} T;moduletest#(N=2,M=3) (outputT A_2D[0:(2**N)-1][0:(2**M)-1] ,outputT A_1D[0:(2**(N+M))-1] );logic[N-1:0] idx_N;logic[M-1:0] idx_M;always_comb begin for(inti = 0; i < 2**N; i++)beginfor(intj = 0; j < 2**M; j++) begin idx_N = i; idx_M = j; A_2D[idx_N][idx_M] = '{i,j}; A_1D[{idx_M,idx_N}] = '{i,j};assert final(A_2D[idx_N][idx_M] == A_1D[{idx_M,idx_N}]);end end end endmodule:test

Advertisements

You have confused transpose with index-position reversal.

These ‘assert final’ statements are trivially true by construction. But in the second example the bitstreams of A_2D and A_1D are no longer identical to each other, because you’ve transposed A_2D into A_1D, instead of copying it as you did in the first example.

The algebra of indexing polynomials does not have the kind of mathematical asymmetry you’re suggesting here. There is no a priori reason to prefer positive to negative strides. Only the choice of 0 as either the origin or anti-origin simplifies the polynomials. If you must work in a language that foists ranged bounds onto all arrays, choose them to best suit the loop indices or semantic uses assigned to each dimension. If you have a choice of language, avoid those with user-defined bounds – they convey nothing you want to know. The very need for loops to build these arrays is appalling to my APL sensibilities.

To illustrate, your first code computes (using []IO←0)

A_2D ← (⏀⍳2*N)◦.,⏀⍳2*M and A_1D ← ,A_2D

and your second example computes

A_2D ← ( ⍳2*N)◦., ⍳2*M and A_1D ← ,⍉A_2D

LikeLike

Correct. I was wrong. Thank you for pointing out my error.

LikeLike