0

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 /* ... */).

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

It turns out the problem with the second error was with my compilation script; the testbenches in the mem_char_disp module were working but they weren't in the mem_char_disp_lib module. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.