I am trying to pass 2D real array to an SV function and return the same but I'm not able to execute this task successfully. Here is a simple reproducible code:
module Two_d_array_pass();
real x[2][2]='{'{1.0,2.0},'{3.0,4.0}};
real y[2][2]='{'{2.0,2.0},'{2.0,2.0}};
real z[2][2];
int i,j;
initial begin
foreach(x[i,j]) $display("x[%0d][%0d]=%0f",i,j,x[i][j]);
foreach(y[i,j]) $display("y[%0d][%0d]=%0f",i,j,y[i][j]);
z=mult(x,y);
end
function real mult(x,y);
real c[2][2];
int i,j;
foreach(c[i,j])
c[i][j]=x[i][j]*y[i][j];
return c;
endfunction
endmodule
and here is the error I get:
file: Two_d_array_pass.sv
c[i][j]=x[i][j]*y[i][j];
|
xmvlog: *E,DIMERR (Two_d_array_pass.sv,18|10): Bit-select or part-select dimensions do not match declaration.
c[i][j]=x[i][j]*y[i][j];
|
xmvlog: *E,DIMERR (Two_d_array_pass.sv,18|18): Bit-select or part-select dimensions do not match declaration.
Can anyone correct the code to achieve this task?
You need to change the arguments to be 2x2 dimensional as well.
function real mult(real x[2][2],y[2][2]);
But you also need to do it for the return type, but because of syntax limitations, unpacked array need a typedef for the return type.
typedef real real2x2[2][2];
function real2x2 mult(real x[2][2],y[2][2]);
Then you might as well use the typedef everywhere
module Two_d_array_pass();
typedef real real2x2[2][2];
real2x2 x='{'{1.0,2.0},'{3.0,4.0}};
real2x2 y='{'{2.0,2.0},'{2.0,2.0}};
real2x2 z;
initial begin
foreach(x[i,j]) $display("x[%0d][%0d]=%0f",i,j,x[i][j]);
foreach(y[i,j]) $display("y[%0d][%0d]=%0f",i,j,y[i][j]);
z=mult(x,y);
end
function real2x2 mult(real2x2 x,y);
foreach(x[i,j])
mult[i][j]=x[i][j]*y[i][j];
endfunction
endmodule
P.S. you do not declare the iterating variables i and j separately, they are implicit and local to the scope of the foreach statement. If you declare them separately, they become extra variables unused by the foreach loop.
first i want to apologize for my ignorance,this question may be stupid for many of you..but i am a newbie in the domain of Hw dev
I am trying to turn a software function into a hardware accelerator...
in the C code we use an array of integer to calculate a certain value as shown here
uint k[64] = {
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
};
as you see here am gonna use it to calculate t1
$ t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
however am not certain how to declare this array without using registers, i have a verilog file in whitch it uses localparam to declare a constant. so i wonder could i use it with this vector as below ?
localparam [31:0] k[63:0] =
{0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
};
Yes you can. However, 0x is not verilog syntax, use 32'h (or just 'h if you want it less strongly typed) instead.
localparam logic [31:0] k[63:0] =
{
32'h428a2f98,32'h71374491,32'hb5c0fbcf,32'he9b5dba5,32'h3956c25b,32'h59f111f1,32'h923f82a4,32'hab1c5ed5,
32'hd807aa98,32'h12835b01,32'h243185be,32'h550c7dc3,32'h72be5d74,32'h80deb1fe,32'h9bdc06a7,32'hc19bf174,
32'he49b69c1,32'hefbe4786,32'h0fc19dc6,32'h240ca1cc,32'h2de92c6f,32'h4a7484aa,32'h5cb0a9dc,32'h76f988da,
32'h983e5152,32'ha831c66d,32'hb00327c8,32'hbf597fc7,32'hc6e00bf3,32'hd5a79147,32'h06ca6351,32'h14292967,
32'h27b70a85,32'h2e1b2138,32'h4d2c6dfc,32'h53380d13,32'h650a7354,32'h766a0abb,32'h81c2c92e,32'h92722c85,
32'ha2bfe8a1,32'ha81a664b,32'hc24b8b70,32'hc76c51a3,32'hd192e819,32'hd6990624,32'hf40e3585,32'h106aa070,
32'h19a4c116,32'h1e376c08,32'h2748774c,32'h34b0bcb5,32'h391c0cb3,32'h4ed8aa4a,32'h5b9cca4f,32'h682e6ff3,
32'h748f82ee,32'h78a5636f,32'h84c87814,32'h8cc70208,32'h90befffa,32'ha4506ceb,32'hbef9a3f7,32'hc67178f2
};
You might be better off going with an integer type rather than localparam. Logic types are 4-state, which is more expensive on the simulator and since you are using it as a constant value (I assume), you should be fine with integer.
integer k[64] = {
32'h428a2f98,32'h71374491,32'hb5c0fbcf,32'he9b5dba5,32'h3956c25b,32'h59f111f1,32'h923f82a4,32'hab1c5ed5,
32'hd807aa98,32'h12835b01,32'h243185be,32'h550c7dc3,32'h72be5d74,32'h80deb1fe,32'h9bdc06a7,32'hc19bf174,
32'he49b69c1,32'hefbe4786,32'h0fc19dc6,32'h240ca1cc,32'h2de92c6f,32'h4a7484aa,32'h5cb0a9dc,32'h76f988da,
32'h983e5152,32'ha831c66d,32'hb00327c8,32'hbf597fc7,32'hc6e00bf3,32'hd5a79147,32'h06ca6351,32'h14292967,
32'h27b70a85,32'h2e1b2138,32'h4d2c6dfc,32'h53380d13,32'h650a7354,32'h766a0abb,32'h81c2c92e,32'h92722c85,
32'ha2bfe8a1,32'ha81a664b,32'hc24b8b70,32'hc76c51a3,32'hd192e819,32'hd6990624,32'hf40e3585,32'h106aa070,
32'h19a4c116,32'h1e376c08,32'h2748774c,32'h34b0bcb5,32'h391c0cb3,32'h4ed8aa4a,32'h5b9cca4f,32'h682e6ff3,
32'h748f82ee,32'h78a5636f,32'h84c87814,32'h8cc70208,32'h90befffa,32'ha4506ceb,32'hbef9a3f7,32'hc67178f2
};
I have a module which stores a bitmap of different characters, that I am planning on using to display text on a matrix. Currently, the bitmap is populated with a memory initialization file, and this file is passed in as a parameter (I have confirmed this working in Quartus and ModelSim).
In order to actually have a lookup table for all the characters, I wanted to make a separate module which has instantiations of the all bitmaps, and selects the correct one based on a character code. These bitmap instantiations are created in a generate block, and they take the correct filename from an array. However, ModelSim doesn't like this. My code is as follows:
module mem_char_disp_lib(
output logic pixel,
input logic [4:0] x,
input logic [5:0] y,
input logic [6:0] code,
input logic clk
);
localparam CHAR_NUM = 26;
logic [CHAR_NUM-1:0] alphabet;
const var [CHAR_NUM-1:0] BITMAPS = {
"/mem/char/A.hex",
"/mem/char/B.hex",
"/mem/char/C.hex",
// ... a lot more declarations here...
"/mem/char/X.hex",
"/mem/char/Y.hex",
"/mem/char/Z.hex"
};
genvar i;
generate
for (i=0; i<CHAR_NUM; i=i+1) begin : mem_char_disp_blocks
mem_char_disp #(.BITMAP(BITMAPS[i])) block (
.pixel(alphabet[i]),
.x, .y, .clk,
.code(i),
.data(1'b0),
.write_en(1'b0)
);
end
endgenerate
always_comb
pixel = alphabet[code];
endmodule
The error ModelSim is giving me is:
The expression for a parameter actual associated with the parameter name ('BITMAP') for the module instance ('block') must be constant.
(referring to the line inside the for loop)
I am not sure why this doesn't work. On a hardware level, it seems like I'm just making a lot of copies of a module, and slightly tweaking each one with a constant parameter known at compile-time. Is there some basic syntax that I'm missing?
Edit: I have also tried the following code, which seems to give a runtime error:
for (i=0; i<CHAR_NUM; i=i+1) begin : mem_char_disp_blocks
parameter [CHAR_NUM-1:0] BITMAPS = {
"/mem/char/A.hex",
// more elements...
"/mem/char/Z.hex"
};
mem_char_disp #(.BITMAP(BITMAPS[i])) block (
.pixel(alphabet[i]),
.x, .y, .clk,
.code(i),
.data(1'b0),
.write_en(1'b0) );
end
The error is Module parameter 'BITMAP' not found for override. (One of these errors for each of the generated modules; CHAR_NUM total.) This doesn't make sense to me, since instantiating a single one directly works just fine (e.g. mem_char_disp #(.BITMAP("/mem/char/A.hex") block /* ... */).
A const variable is not a constant - it is a write-once variable that gets initialized at runtime when the variable gets allocated. You need to us a parameter or localparam to assign to another parameter as you discovered in your update. You also need to fix the dimensions of the array
parameter bit [1:15*8] BITMAPS[26] = {
"/mem/char/A.hex", // 15 8-bit chars
// more elements...
"/mem/char/Z.hex" // 26 elements
};
Can't help you with your last error without seeing the declaration of the module mem_char_disp