Search code examples
verilogfpgasystem-verilogquartus

Can't create symbole file for module because port has unsupported type


I am having this weird problem where Quartus won't generate the symbole file for the following code:

module bin_to_bcd #(parameter N_DIGITS = 4) (count, bcd_output);

input wire [$clog2(9999)-1:0] count;
output reg [(N_DIGITS<<2)-1:0] bcd_output;

integer i;
integer decade;

always @ (count) begin
    bcd_output = 'b0;
    for(i = $clog2(9999) - 1; i >= 0; i = i - 1) begin
        for(decade = 1; decade < N_DIGITS + 1; decade = decade + 1) begin
            if(bcd_output[(decade<<2) - 1 -: 4] >= 5) begin
                bcd_output[(decade<<2) - 1 -: 4] = bcd_output[(decade<<2) - 1 -: 4] + 3;
            end
        end

        bcd_output = bcd_output << 1;
        bcd_output[0] = count[i];
    end
end

endmodule

The error that is thrown is :

10016 Can't create symbol/include/instantiation/component file for module "bin_to_bcd" because port "count" has an unsupported type

But "count" is an "input wire" as it should be and I have other similar code that work just fine. Maybe I'm missing something obvious but I would greatly appreciate any help I can get.

I should also mention that this code works perfectly fine in simulation in ModelSim-Altera.

Thanks.

EDIT: I would also like to be able to specify a number of digit for the output as a parameter if anyone as any idea how to implement this. Note: $clog2({N_DIGITS{9}}) does not work...

EDIT #2 : I'm sorry if I am responding slowly I was working on something else. So the problem still presents itslef and I haven't figure out why... Here is some insight that might be useful. The following code works perfectly fine and uses the same type of register sizing with $clog2. If someone sees any differences between the code I posted and this one, please step forward and shout "I FOUND IT!", because this is driving me crazy :P

module multiplexer #(parameter N_INPUTS = 2, parameter N_OUTPUTS = 1) (in, out, select);

generate
    if (N_INPUTS % N_OUTPUTS != 0) begin
        illegal_parameter_cant_divide_inputs_by_outputs non_existing_module();
    end
endgenerate

input wire [N_INPUTS-1:0] in;
input wire [$clog2(N_INPUTS/N_OUTPUTS) - 1:0] select; //THIS LINE WORKS FINE
output wire [N_OUTPUTS-1:0] out;

assign out = in[(select + 1) * N_OUTPUTS - 1 -: N_OUTPUTS];

endmodule

Edit #3 : I actually just noticed that the multiplexer code did not get synthesized properly as a symbol (the select port is missing... I applied the same fix and it's OK now).

Again, any help would be greatly appreciated.


Solution

  • From Verilog-2005 and SystemVerilog syntax, I cannot spot anything wrong with your code. It ran fine on EDAplayground with various simulators. If bin_to_bcd is in a .v file and multiplexer has a .sv file, then it could be it could be how the file is being parsed. $clog2 is not a build-in type for Verilog-2001, you you might want to make sure Verilog files are being parsed as 2005 and not 2001. Though I recommend using the SystemVerilog .sv file type.

    As for makking $clog2(9999) scale based on N_DIGITS, use $clog2(10**N_DIGITS-1).

    You might also want to assign $clog2(...) to a parameter. ANSI header style example:

    module bin_to_bcd #(
      parameter N_DIGITS = 4,
      parameter IN_BITS = $clog2(10**N_DIGITS-1)
    ) (
      input wire [IN_BITS-1:0] count,
      output reg [(N_DIGITS<<2)-1:0] bcd_output );