blob: 996db53780c8db21135c0cd3c7e5914d16881b70 [file] [log] [blame]
`default_nettype none
module chrisruk_matrix #( parameter MAX_COUNT = 1000 ) (
input [7:0] io_in,
output [7:0] io_out
);
wire clk = io_in[0]; // Input clock line
wire reset = io_in[1]; // Input reset line
wire digit1 = io_in[2]; // Digit to display
reg [0:0] digit1_cache; // Cache of first digit
reg [0:0] digit2_cache; // Cache of second digit
reg [0:0] clock_1; // Clock output
reg [0:0] strip_1; // Data output
reg [0:0] first; // Whether this is first digit displayed, if so display 'blank' character
assign io_out[0] = clock_1; // Clock output for LED matrix
assign io_out[1] = strip_1; // Data output for LED matrix
reg [0:40-1] fonts [0:2-1]; // Font array
reg [11:0] counter1; // Count where we are in bit pattern
reg [2:0] shift; // Amount to left shift character
reg [3-1:0] rowno; // Row number in 8x8 matrix
reg [6-1:0] idx; // Bit index within colour register
reg [6-1:0] pidx; // Bit index within character, we apply processing on top of this
// value to create the bitidx value
reg [6-1:0] bitidx; // Index of bit we are within of character
reg [0:32-1] ledreg1; // Colour 1
reg [0:32-1] ledreg2; // Colour 2
reg [0:64-1] display; // Display buffer
`ifdef FPGA
// Generate 6kHz clock from input 12MHz clock
reg [0:0] clk2;
integer counter;
reg [0:0] resetflag;
initial begin
first = 1; // For FPGA for some reason need to have this here too, otherwise we get duplicate first value
clk2 = 0;
counter = 0;
resetflag = 1; // Reset flag, only used by FPGA
end
always @(posedge clk) begin
if (counter == 2000) begin // Create 6kHz clock
clk2 = ~clk2;
counter = 0;
end else begin
counter <= counter + 1;
end
end
always @(posedge clk2) begin
if (reset || resetflag) begin
resetflag <= 0;
`else
always @(posedge clk) begin
if (reset) begin
`endif
// Setup variables
shift <= 0;
counter1 <= 0;
idx <= 0;
bitidx <= 0;
pidx <= 0;
strip_1 <= 0;
clock_1 <= 0;
ledreg1 <= 32'hf0000f00; // Number colour
ledreg2 <= 32'hf0070000; // Background colour
fonts[0] <= 40'h18_24_24_24_18; // 0
fonts[1] <= 40'h18_28_08_08_3e; // 1
digit1_cache <= 0;
digit2_cache <= digit1;
first = 1;
end else begin
clock_1 = ~clock_1 ;
if (clock_1 == 1) begin
if (counter1 < 32) begin
strip_1 = 0;
// Provided we're not displaying first digit in scrolling marquee pattern, display digit
// and shift each time
if(!first) begin
display = {16'b0,
fonts[digit1_cache][32:39] << shift,
fonts[digit1_cache][24:31] << shift,
fonts[digit1_cache][16:23] << shift,
fonts[digit1_cache][8:15] << shift,
fonts[digit1_cache][0:7] << shift,
8'b0};
end else begin
display = 0;
end
// Display part of next digit too
display = display | {16'b0,
fonts[digit2_cache][32:39] >> 8 - shift,
fonts[digit2_cache][24:31] >> 8 - shift,
fonts[digit2_cache][16:23] >> 8 - shift,
fonts[digit2_cache][8:15] >> 8 - shift,
fonts[digit2_cache][0:7] >> 8 - shift,
8'b0};
end else if (counter1 < 32 + (32 * (8*8))) begin
rowno = pidx / 8;
// Flip bit order if even row, as matrix of LEDs
// is in a 'snake' like pattern
if(rowno % 2 == 0) begin
bitidx = ((rowno * 16) + 8) - 1 - pidx;
end else begin
bitidx = pidx;
end
// Extract bit from display buffer
if (display[bitidx] == 1) begin
strip_1 = ledreg1[idx];
end else begin
strip_1 = ledreg2[idx];
end
idx = idx + 1;
if (idx == 32) begin
idx = 0;
pidx = pidx + 1;
end
end else if (counter1 < 32 + (32 * (8*8)) + 32 + 32) begin
// Need zeros at end of pattern
strip_1 = 0;
end else begin
counter1 = 0;
pidx = 0;
idx = 0;
if (shift == 7) begin
digit1_cache = digit2_cache;
digit2_cache = digit1; // Grab next digit to be displayed from input pin
shift = 0;
first = 0;
end else begin
// Need to wrap back to first letter
shift = shift + 1;
end
end
counter1 = counter1 + 1;
end
end
end
endmodule