verilogfpgahdlled

Issue with driving an LED matrix using an FPGA (Verilog)


I am trying to run an LED matrix using an FPGA. The specifics are a TinyFPGA BX, wired into this board (driver chip datasheet), connected to this screen. Before this, I managed to drive this matrix using a Raspberry pi directly, which I am basing my code on. There I ran into issues with how fast I could refresh the thing, so I moved into trying to drive it with an FPGA. Currently I am attempting to drive it using BCM however the output I am getting is different coloured lines shifting left on the screen, seemingly completely random. Expected behaviour is a brown colour.

Here is my current display loop, full project here (apologies for the messy code):

    integer _x = 0; // x is already used in verilog
    integer y = 0;
    integer bit = 0;
    integer bcm_delay = 1;
    integer bcm_counter = 1;
    always @(posedge CLK) begin
        // TODO: colour depth

        if (bcm_counter >= (bcm_delay << bit)) begin
            ctrl_lat = 0; // Close latch to load in next data

            // Load colours
            col_buff[0] = colour[bit];                          // R1
            col_buff[1] = colour[bit];                          // R2
            col_buff[2] = colour[bit + bit_depth];              // G1
            col_buff[3] = colour[bit + bit_depth];              // G2
            col_buff[4] = colour[bit + bit_depth + bit_depth];  // B1
            col_buff[5] = colour[bit + bit_depth + bit_depth];  // B2
            
            ctrl_clk = 1;
            ctrl_clk = 0;

            _x = _x + 1;

            // Commit loaded colours
            if (_x >= width) begin
                _x = 0;

                ctrl_lat = 1; // Open latch to commit colours

                bit = bit + 1;
                bcm_counter = 1;
            end

            if (bit >= bit_depth) begin
                bit = 0;
                _address = _address + 1;
            end
            
            if (_address >= halfwidth) _address = 0;
        end

        bcm_counter = bcm_counter + 1;

        pwm_counter <= pwm_counter + 1; // PWM at clock frequency
    end

I cannot get this to work. Incorrect BCM counter incrementing might be the issue; however, I would expect that to effect colour depth instead of having these lines shifting left. for loops seem to not be synthesizable on the FPGA, hence the counters and if statements. Any help debugging would be greatly appreciated.


Solution

  • Any help debugging would be greatly appreciated

    Programming Verilog code into an FPGA is a methodology with several steps, but you are skipping some of them:

    I see some potential problems in the Verilog code snippet that you posted into the question:

    Nonblocking assignments should be used to model sequential logic. Using blocking assignments there will likely cause Verilog simulations to produce unexpected results.

    You should make yourself familiar with synthesizable good practices. Your FPGA toolchain documentation might have some good guidelines.

    You should simulate the Verilog code before synthesis, if you are not already doing so. You need to create a Verilog testbench if your toolchain does not create one for you. You need to drive the inputs with some basic patterns and look at waveforms of your outputs to make sure they behave as expected.

    After you synthesize the code for the FPGA, you must review all the synthesis reports. Check for error and warning messages. Sometimes these are buried, so you might need to go looking for them.

    for loops seem to not be synthesizable on the FPGA

    That is one possibility. Another possibility is that you have a syntax error in your for loops. It is much simpler to debug syntax errors in simulation.

    You should change the name of the bit signal because it is a reserved keyword in SystemVerilog. Perhaps name it bit_count.

    // x is already used in verilog

    It is legal to use x as a signal name, but it is a bad idea to do so because it is easily confused with the 4-state unknown value x. A more descriptive name would be something like x_count.