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.
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:
=
) instead nonblocking (<=
) assignments in the always
block.bit
) in independent if
statementsNonblocking 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
.