Author Topic: LED Matrix Logic  (Read 800 times)

0 Members and 1 Guest are viewing this topic.

Offline FoxxzTopic starter

  • Regular Contributor
  • *
  • Posts: 122
  • Country: us
LED Matrix Logic
« on: May 26, 2022, 04:23:34 pm »
I wanted to write a verilog module to drive a led matrix (schematic attached). For now I just wanted to drive the left side (matrix A) and address the LEDs 0-71 from left to right, top to bottom.

I wanted to parameterize the number of matrix lines in verilog module but couldn't figure out a way to write the decode logic based on the parameter (IE - 9 in this case). If not that then using a generate block to build the case statement.

Sometimes I miss the obvious so please point it out to me if I have.

Code: [Select]
module led_matrix (
input [6:0] pixel_addr,
input led_sig,
output reg [8:0] matrix
);

always @(*) begin
if (!led_sig)
matrix <= 9'bz;
else
case(pixel_addr)
0 : matrix <= 9'b01zzzzzzz;
1 : matrix <= 9'b0z1zzzzzz;
2 : matrix <= 9'b0zz1zzzzz;
3 : matrix <= 9'b0zzz1zzzz;
4 : matrix <= 9'b0zzzz1zzz;
5 : matrix <= 9'b0zzzzz1zz;
6 : matrix <= 9'b0zzzzzz1z;
7 : matrix <= 9'b0zzzzzzz1;

8 : matrix <= 9'b10zzzzzzz;
9 : matrix <= 9'bz01zzzzzz;
10 : matrix <= 9'bz0z1zzzzz;
11 : matrix <= 9'bz0zz1zzzz;
12 : matrix <= 9'bz0zzz1zzz;
13 : matrix <= 9'bz0zzzz1zz;
14 : matrix <= 9'bz0zzzzz1z;
15 : matrix <= 9'bz0zzzzzz1;

16 : matrix <= 9'b1z0zzzzzz;
17 : matrix <= 9'bz10zzzzzz;
18 : matrix <= 9'bzz01zzzzz;
19 : matrix <= 9'bzz0z1zzzz;
20 : matrix <= 9'bzz0zz1zzz;
21 : matrix <= 9'bzz0zzz1zz;
22 : matrix <= 9'bzz0zzzz1z;
23 : matrix <= 9'bzz0zzzzz1;

24 : matrix <= 9'b1zz0zzzzz;
25 : matrix <= 9'bz1z0zzzzz;
26 : matrix <= 9'bzz10zzzzz;
27 : matrix <= 9'bzzz01zzzz;
28 : matrix <= 9'bzzz0z1zzz;
29 : matrix <= 9'bzzz0zz1zz;
30 : matrix <= 9'bzzz0zzz1z;
31 : matrix <= 9'bzzz0zzzz1;

32 : matrix <= 9'b1zzz0zzzz;
33 : matrix <= 9'bz1zz0zzzz;
34 : matrix <= 9'bzz1z0zzzz;
35 : matrix <= 9'bzzz10zzzz;
36 : matrix <= 9'bzzzz01zzz;
37 : matrix <= 9'bzzzz0z1zz;
38 : matrix <= 9'bzzzz0zz1z;
39 : matrix <= 9'bzzzz0zzz1;

40 : matrix <= 9'b1zzzz0zzz;
41 : matrix <= 9'bz1zzz0zzz;
42 : matrix <= 9'bzz1zz0zzz;
43 : matrix <= 9'bzzz1z0zzz;
44 : matrix <= 9'bzzzz10zzz;
45 : matrix <= 9'bzzzzz01zz;
46 : matrix <= 9'bzzzzz0z1z;
47 : matrix <= 9'bzzzzz0zz1;

48 : matrix <= 9'b1zzzzz0zz;
49 : matrix <= 9'bz1zzzz0zz;
50 : matrix <= 9'bzz1zzz0zz;
51 : matrix <= 9'bzzz1zz0zz;
52 : matrix <= 9'bzzzz1z0zz;
53 : matrix <= 9'bzzzzz10zz;
54 : matrix <= 9'bzzzzzz01z;
55 : matrix <= 9'bzzzzzz0z1;

56 : matrix <= 9'b1zzzzzz0z;
57 : matrix <= 9'bz1zzzzz0z;
58 : matrix <= 9'bzz1zzzz0z;
59 : matrix <= 9'bzzz1zzz0z;
60 : matrix <= 9'bzzzz1zz0z;
61 : matrix <= 9'bzzzzz1z0z;
62 : matrix <= 9'bzzzzzz10z;
63 : matrix <= 9'bzzzzzzz01;

64 : matrix <= 9'b1zzzzzzz0;
65 : matrix <= 9'bz1zzzzzz0;
66 : matrix <= 9'bzz1zzzzz0;
67 : matrix <= 9'bzzz1zzzz0;
68 : matrix <= 9'bzzzz1zzz0;
69 : matrix <= 9'bzzzzz1zz0;
70 : matrix <= 9'bzzzzzz1z0;
71 : matrix <= 9'bzzzzzzz10;

default: matrix <= 9'bz;
endcase
end

endmodule
 

Offline josuah

  • Regular Contributor
  • *
  • Posts: 119
  • Country: fr
    • josuah.net
Re: LED Matrix Logic
« Reply #1 on: May 27, 2022, 01:36:30 pm »
Charlieplexing is fun!

Your implementation already displays a nice visual way to get around with that.

It could be convenient to transform these individual addresses to x/y coordinates... Maybe just splitting the bits of the address would suffice since you have 8 pixel per row.

Focusing on the first row, how to get the right pins Low/High/High-Z for each position?

There might be something to do with the "<<" operator, to shift a bit by as much as a binary number tells us.
With that we can already make the first row!

Due to how charlieplexing work, and as you figured out, there is the need to skip a position while row == column, as well as everything after that.

That looks like about trying to build-up the bitshift, then adjusting the shift amount when (row >= columns).


P.S.: I might have mistaken rows for columns at a few places!
 

Offline FoxxzTopic starter

  • Regular Contributor
  • *
  • Posts: 122
  • Country: us
Re: LED Matrix Logic
« Reply #2 on: May 27, 2022, 02:21:22 pm »
Thanks for your reply. In the code above I have them broken up into rows such as 0-7.

You brought up a good point that I might want to try x and y addressing which I will most likely build an additional module for even if it's just a translation layer. The original module was written with the intent of being fed from a frame buffer so at the time it made sense.

After using the existing module for a while I may have come up with a way to accomplish what I originally asked.

As it stands the existing module occupies 2 BRAMs. Not bad. Not great :-) I'm all about better efficiency though.
 

Offline FoxxzTopic starter

  • Regular Contributor
  • *
  • Posts: 122
  • Country: us
Re: LED Matrix Logic
« Reply #3 on: May 28, 2022, 12:01:02 am »
As Dave would say:
For those playing along at home I was able to come up with a solution that uses only logic. My prior module using lookup tables occupied 2x 4kbit block rams. This new solution uses 16x LUT4s. And I should be able to parameterize it easily.

Code: [Select]
module led_matrix_two (
input [6:0] pixel_addr,
input led_sig,
output reg [8:0] matrix
);

always @* begin
matrix = 9'bz;
if (led_sig) begin
matrix[8 - pixel_addr[6:3]] = 0;
matrix[pixel_addr[6:3] <= pixel_addr[2:0] ? 7 - pixel_addr[2:0] : 8 - pixel_addr[2:0]] = 1;
end
end

endmodule

« Last Edit: May 28, 2022, 03:01:53 am by Foxxz »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf