Buriedcode
Full Member level 6
Hi,
I'm relatively new to verilog (avoided VHDL like the plague) but decided to use it for a complicated logic block I need for an LCD controller - it takes in 3 single bit inputs, R,G and B, and outputs three bytes sequentially. It reads in the RGB inputs 8 times, and outputs the three 3 bytes. ( 8 X 3 inputs = 24 bits. = 3 bytes).
A byte is sent out after 4 input reads, another after another 4 input reads, then, sometime later, the last byte.
This is essentially a state machine, so I've included a 4-bit counter to count from 0 to 11 (12 states). I've uesd a 'case' statement for each of the states 0-7, but I only need one thing done in states 8-11, therefore, I picked state 10. In the states I do not need anything done, I have simpley put
b[15:0] <= b[15:0]; // Hoping the fitter will realise this doesn't actually do anything.
I'm using 16 registers as temporary storage, plus 4 for the counter, plus inevitably some more for combinatorial. However, Quartus has generated something with 28 macrocells. I understand that its not an easy problem, but I fear these extra macrocells are generated because of my poor coding style, and so, I've provided the module, with hope that someone can point out flaws. I am not asking for confirmation of functionality (it works exactly as I intended), but more for optimization as every macrocell counts in this design:
The counter is sent to an output purely for simulation so I can see what value the counter is at a particular time. It is quite a complicated idea but its the only way I can format the input data for a colour-STN LCD.
Does adding 'assign dout = b[15:8]' add more macrocells? Or perhaps using cntout as an output instead of explicitly using 'counter' as an output? You guys with FPGA's probably have the resources to not bother, but this is a 64 macrocell CPLD, so I'm tryin my best to make this as efficient as possible
Thanks, Buriedcode
I'm relatively new to verilog (avoided VHDL like the plague) but decided to use it for a complicated logic block I need for an LCD controller - it takes in 3 single bit inputs, R,G and B, and outputs three bytes sequentially. It reads in the RGB inputs 8 times, and outputs the three 3 bytes. ( 8 X 3 inputs = 24 bits. = 3 bytes).
A byte is sent out after 4 input reads, another after another 4 input reads, then, sometime later, the last byte.
This is essentially a state machine, so I've included a 4-bit counter to count from 0 to 11 (12 states). I've uesd a 'case' statement for each of the states 0-7, but I only need one thing done in states 8-11, therefore, I picked state 10. In the states I do not need anything done, I have simpley put
b[15:0] <= b[15:0]; // Hoping the fitter will realise this doesn't actually do anything.
I'm using 16 registers as temporary storage, plus 4 for the counter, plus inevitably some more for combinatorial. However, Quartus has generated something with 28 macrocells. I understand that its not an easy problem, but I fear these extra macrocells are generated because of my poor coding style, and so, I've provided the module, with hope that someone can point out flaws. I am not asking for confirmation of functionality (it works exactly as I intended), but more for optimization as every macrocell counts in this design:
Code:
module LCDcolfmat(clkin,cntout,dout,R,G,B,reset);
reg [15:0] b;
reg [3:0] counter;
wire cntmax = (counter==11);
input clkin;
input reset;
input R;
input G;
input B;
output [7:0] dout;
output [3:0] cntout;
wire [7:0] dout;
always @(posedge clkin)
begin
if(reset|cntmax)
counter <= 0;
else
counter <= counter + 1;
end
always @(posedge clkin)
case(counter)
0: b[15:13] <= {R,G,B}; // fill up buffer with pixel 1
1: b[12:10] <= {R,G,B}; // pixel 2
2: b[9:7] <= {R,G,B}; // pixel 3
3: b[6:4] <= {R,G,B}; // pixel 4 - b[15:8] read out here from external latch
4: begin
b[15:12] <= b[7:4]; // move lower byte to upper, last 4 bits don't care.
b[11:9] <= {R,G,B}; // pixel 5
end
5: b[8:6] <= {R,G,B}; // pixel 6
6: b[5:3] <= {R,G,B}; // pixel 7
7: b[2:0] <= {R,G,B}; // pixel 8 - b[15:8] read out here from external latch
8: b[15:0] <= b[15:0]; // do nothing
9: b[15:0] <= b[15:0]; // do nothing
10: b[15:8] <= b[7:0]; // send lower byte of buffer to upper byte, can this be optimsed?
11: b[15:0] <= b[15:0]; // do nothing - b[15:8] read out here from external latch
endcase
assign dout = b[15:8];
assign cntout = counter;
endmodule
The counter is sent to an output purely for simulation so I can see what value the counter is at a particular time. It is quite a complicated idea but its the only way I can format the input data for a colour-STN LCD.
Does adding 'assign dout = b[15:8]' add more macrocells? Or perhaps using cntout as an output instead of explicitly using 'counter' as an output? You guys with FPGA's probably have the resources to not bother, but this is a 64 macrocell CPLD, so I'm tryin my best to make this as efficient as possible
Thanks, Buriedcode