Verilog - digital clock- Minute doesnt work - timer

im implementing a digital clock with verilog. I count clk's and so count seconds. Then i sent outputs to seven segment display. My second display works perfectly, but minute's doesnt work . Some times , it displays like , in first increase 60, in second 2 , third 45 60 anything, fourth 4.
I created split module which takes 1 input give 2 output. Like
if input = 56 , output 1 = 5 , output 2=6 . Works perfect in simulation and for second.
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 23:36:40 11/05/2015
// Design Name:
// Module Name: Top
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Top(input clk,reset,input in0, in1, in2, in3,output a, b, c, d, e, f, g, dp,output [3:0] an
);
wire [3:0] minLeft,minRight;
wire [3:0] secLeft,secRight;
wire [6:0] second,minute;
wire[4:0] hour;
wire newDay;
split_output sec(second,secLeft,secRight);
split_output split(minute,minLeft,minRight);
Clock timer(clk,second,minute,hour,newDay);
sevenseg decoder(clk,reset,minLeft,minRight,secLeft,secRight,a,b,c,d,e,f,g,dp,an);
endmodule
CLOCK MODULE
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 21:26:35 11/05/2015
// Design Name:
// Module Name: Clock
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Clock(input clk,output [6:0] second,minute,output [4:0] hour,output reg newDay
);
//Clock counter for second
reg [25:0]cnt_clk=0;
//Second counter
reg [6:0]cnt_second=0;
//Minutes counter
reg [6:0]cnt_minute=0;
//Hour counter
reg [4:0]cnt_hour=0;
assign second=cnt_second;
assign minute=cnt_minute;
assign hour=cnt_hour;
//COUNT CLOCK, INCREASE SECOND
always#(*)
begin
// IF CLOCK COUNT İS 1 SECOND
if(cnt_clk==26'd5000000)
begin
cnt_clk=26'd0;
// IF SECOND COUNT İS 60, RESET İT
if(cnt_second==7'b0111100)
begin
cnt_second<=7'b0000000;
end
else
begin
cnt_second<=cnt_second+1;
end
end
else
begin
cnt_clk=cnt_clk+1;
end
end
// UPDATE MİNUTES, AS SECONDS INCREASE
always#(cnt_second)
begin
//IF ITS 1 MINUTES
if(cnt_second==7'd60)
begin
if(cnt_minute==7'd60)
begin
cnt_minute<=0;
end
else
begin
cnt_minute=cnt_minute+1;
end
end
end
//UPDATE HOURS,AS MİNUTES INCREASE
always#(cnt_minute)
begin
//IF ITS 60 MINUTES
if(cnt_minute==7'b0111100)
begin
if(cnt_hour==5'b11000)
begin
cnt_hour<=5'b00000;
end
else
begin
cnt_hour<=cnt_hour+1;
end
end
end
// IF THE DAY İS OVER
always#(cnt_hour)
begin
if(cnt_hour==5'b11000)
begin
newDay=1;
end
else
begin
newDay=0;
end
end
endmodule
SPLİT MODULE
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 18:51:22 11/09/2015
// Design Name:
// Module Name: split_output
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module split_output(input [7:0] total,output reg[3:0] left,right
);
always#(total)
begin
if(total>=8'b00110010&&total<8'b00111100)
begin
assign left=4'b0101;
assign right=total-50;
end
if(total>=8'b00101000&&total<8'b00110010)
begin
assign left=4'b0100;
assign right=total-40;
end
if(total>=8'b00011110&&total<8'b00101000)
begin
assign left=4'b0011;
assign right=total-30;
end
if(total>=8'b00010100&&total<8'b00011110)
begin
assign left=4'b0010;
assign right=total-20;
end
if(total>=8'b00001010&&total<8'b00010100)
begin
assign left=4'b0001;
assign right=total-10;
end
if(total<8'b00001010)
begin
assign left=0;
assign right=total;
end
if(total==8'b00111100)
begin
assign left=4'b0110;
assign right=0;
end
end
endmodule
7seg decoder- i found in that site- it works perfect( THANKS TO WHO PUBLİSHED AGAİN)
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 23:31:47 11/05/2015
// Design Name:
// Module Name: sevenseg
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module sevenseg(
input clock, reset,
input [3:0] in0, in1, in2, in3, //the 4 inputs for each display
output a, b, c, d, e, f, g, dp, //the individual LED output for the seven segment along with the digital point
output [3:0] an // the 4 bit enable signal
);
localparam N = 18;
reg [N-1:0]count; //the 18 bit counter which allows us to multiplex at 1000Hz
always # (posedge clock or posedge reset)
begin
if (reset)
count <= 0;
else
count <= count + 1;
end
reg [6:0]sseg; //the 7 bit register to hold the data to output
reg [3:0]an_temp; //register for the 4 bit enable
always # (*)
begin
case(count[N-1:N-2]) //using only the 2 MSB's of the counter
2'b00 : //When the 2 MSB's are 00 enable the fourth display
begin
sseg = in0;
an_temp = 4'b1110;
end
2'b01: //When the 2 MSB's are 01 enable the third display
begin
sseg = in1;
an_temp = 4'b1101;
end
2'b10: //When the 2 MSB's are 10 enable the second display
begin
sseg = in2;
an_temp = 4'b1011;
end
2'b11: //When the 2 MSB's are 11 enable the first display
begin
sseg = in3;
an_temp = 4'b0111;
end
endcase
end
assign an = an_temp;
reg [6:0] sseg_temp; // 7 bit register to hold the binary value of each input given
always # (*)
begin
case(sseg)
4'd0 : sseg_temp = 7'b1000000; //to display 0
4'd1 : sseg_temp = 7'b1111001; //to display 1
4'd2 : sseg_temp = 7'b0100100; //to display 2
4'd3 : sseg_temp = 7'b0110000; //to display 3
4'd4 : sseg_temp = 7'b0011001; //to display 4
4'd5 : sseg_temp = 7'b0010010; //to display 5
4'd6 : sseg_temp = 7'b0000010; //to display 6
4'd7 : sseg_temp = 7'b1111000; //to display 7
4'd8 : sseg_temp = 7'b0000000; //to display 8
4'd9 : sseg_temp = 7'b0010000; //to display 9
default : sseg_temp = 7'b0111111; //dash
endcase
end
assign {g, f, e, d, c, b, a} = sseg_temp; //concatenate the outputs to the register, this is just a more neat way of doing this.
// I could have done in the case statement: 4'd0 : {g, f, e, d, c, b, a} = 7'b1000000;
// its the same thing.. write however you like it
assign dp = 1'b1; //since the decimal point is not needed, all 4 of them are turned off
endmodule
MY UCF
NET "reset" LOC = "a7";
# Pin assignment for 7-segment displays
NET "a" LOC = "l14" ;
NET "b" LOC = "h12" ;
NET "c" LOC = "n14" ;
NET "d" LOC = "n11" ;
NET "e" LOC = "p12" ;
NET "f" LOC = "l13" ;
NET "g" LOC = "m12" ;
NET "dp" LOC = "n13" ;
NET "an[0]" LOC = "k14";
NET "an[1]" LOC = "m13";
NET "an[2]" LOC = "j12";
NET "an[3]" LOC = "f12";
# Pin assignment for clock
NET "clk" LOC = "b8";

Blocking (=) vs non-blocking (<=) been answered may times:
How to interpret blocking vs non blocking assignments in Verilog?
Verilog Blocking Assignment
Nonblocking Assignments in Verilog Synthesis, Coding
Styles That Kill! (Cliff Cummings paper)
Latches are inferred when a reg is not assigned in all possible branches within a otherwise conbinational block. If you want latches, put them in a separate always block, away from the combinational logic, use non-blocking (<=) assignments, and keep them as simple assignments. Doing so will remove the confusion of what is intended to be decoding logic, level sensitive latches, and edge sensitive flip-flops. Combinational loops are another hazard. This is where you get different results if you run the same combinational block two or more times with the same inputs in the same time stamp and get different outputs.
When it comes to RTL coding style, I typically follow Cliff Cummings' recommendations, such as:
The Fundamentals of Efficient Synthesizable Finite State Machine
Design
Coding And Scripting Techniques For FSM Designs With
Synthesis-Optimized, Glitch-Free Outputs
There are additional links to useful Verilog/SystemVerilog references in my profile. I personally do not like nested conditional statements (?:). From experience, I get better synthesis results using case statements when there are more then two possibilities.
Here is an incomplete example how I would code Clock and split_output. I'll leave the rest for you figure out and learn on your own.
module Clock(
input clk,
output reg [5:0] second, minute,
output reg [3:0] hour,
output reg newDay
);
// ... declare local regs
// SYNCHRONOUS ASSIGNMENTS
always #(posedge clk) begin
cnt_clk <= next_cnt_clk;
second <= next_second;
// ... other assignments
end
// COMBINATIONAL CALCULATIONS
always #* begin
// DEFAULT VALUES
next_cnt_clk = cnt_clk + 1;
next_second = second;
// ... other default
// IF CLOCK COUNT İS 1 SECOND
if (next_cnt_clk == 24'd5000000) begin
next_cnt_clk = 24'd0;
next_second = second + 1;
end
// IF SECOND COUNT İS 60, RESET İT
if (next_second == 6'd60) begin
next_second = 6'd0;
next_minute = minute + 1;
end
// ... other calculations
end
endmodule
module split_output(
input [5:0] total,
output reg [3:0] left, right
);
always #* begin
if (total < 8'd10) begin
left = 4'b0000;
right = total[3:0];
end
else if (total < 8'd20) begin
left = 4'b0001;
right = total-10;
end
// ... other 'else if'
else begin // final is 'else'
left = 4'b0110;
right = 4'b0000;
end
end
endmodule

Related

List of valid operations in Tensorflow

I am using (learning) Tensorflow through the eager C API, or to be even more precise through a FreePascal wrapper around it.
When I want to do e.g. a matrix multiplication, I call
TFE_Execute(Op, #OutTensH, #NumOutVals, Status);
where Op.Op_Name is 'MatMul'. I have a couple of other instructions figured out, e.g. 'Transpose', 'Softmax', 'Inv', etc., but I do not have a complete list. In particular I want to get the determinant of a matrix, but cannot find it (assume it exists). I tried to find it on the web, as well as in the source on GitHub, but no success.
In Python there is tf.linalg.det, but already in C++ API I do not find it.
Could someone direct me to a place where I can find a complete list of supported operations?
Can someone tell me how to calculate the determinant with Tensorflow?
Edit: On Gaurav's request I attach a small program. As said above, it is in Pascal, and calls the C API through a wrapper. I therefore copied also the relevant part of the wrapper here (full version: https://macpgmr.github.io/). The set-up works, the "only" question is that I do not find a list of supported operations.
// A minimal program to transpose a matrix
program test;
uses
SysUtils,
TF;
var
Tensor:TTensor;
begin
Tensor:=TTensor.CreateSingle([2,1],[1.0,2.0]);
writeln('Before transpose ',Tensor.Dim[0],' x ',Tensor.Dim[1]); // 2 x 1
Tensor:=Tensor.Temp.ExecOp('Transpose',TTensor.CreateInt32([1,0]).Temp);
writeln('After transpose ',Tensor.Dim[0],' x ',Tensor.Dim[1]); // 1 x 2
FreeAndNil(Tensor);
end.
// extract from TF.pas ( (C) Phil Hess ). It basically re-packages the operation
// and calls the relevant C TFE_Execute, with the same operation name passed on:
// in our case 'Transpose'.
// I am looking for a complete list of supported operations.
function TTensor.ExecOp(const OpName : string;
Tensor2 : TTensor = nil;
Tensor3 : TTensor = nil;
Tensor4 : TTensor = nil) : TTensor;
var
Status : TF_StatusPtr;
Op : TFE_OpPtr;
NumOutVals : cint;
OutTensH : TFE_TensorHandlePtr;
begin
Result := nil;
Status := TF_NewStatus();
Op := TFE_NewOp(Context, PAnsiChar(OpName), Status);
try
if not CheckStatus(Status) then
Exit;
{Add operation input tensors}
TFE_OpAddInput(Op, TensorH, Status);
if not CheckStatus(Status) then
Exit;
if Assigned(Tensor2) then {Operation has 2nd tensor input?}
begin
TFE_OpAddInput(Op, Tensor2.TensorH, Status);
if not CheckStatus(Status) then
Exit;
end;
if Assigned(Tensor3) then {Operation has 3rd tensor input?}
begin
TFE_OpAddInput(Op, Tensor3.TensorH, Status);
if not CheckStatus(Status) then
Exit;
end;
if Assigned(Tensor4) then {Operation has 4th tensor input?}
begin
TFE_OpAddInput(Op, Tensor4.TensorH, Status);
if not CheckStatus(Status) then
Exit;
end;
{Set operation attributes}
TFE_OpSetAttrType(Op, 'T', DataType); //typically result type same as input's
if OpName = 'MatMul' then
begin
TFE_OpSetAttrBool(Op, 'transpose_a', #0); //default (False)
TFE_OpSetAttrBool(Op, 'transpose_b', #0); //default (False)
end
else if OpName = 'Transpose' then
TFE_OpSetAttrType(Op, 'Tperm', Tensor2.DataType) //permutations type
else if OpName = 'Sum' then
begin
TFE_OpSetAttrType(Op, 'Tidx', Tensor2.DataType); //reduction_indices type
TFE_OpSetAttrBool(Op, 'keep_dims', #0); //default (False)
end
else if (OpName = 'RandomUniform') or (OpName = 'RandomStandardNormal') then
begin
TFE_OpSetAttrInt(Op, 'seed', 0); //default
TFE_OpSetAttrInt(Op, 'seed2', 0); //default
TFE_OpSetAttrType(Op, 'dtype', TF_FLOAT); //for now, use this as result type
end
else if OpName = 'OneHot' then
begin
TFE_OpSetAttrType(Op, 'T', Tensor3.DataType); //result type must be same as on/off
TFE_OpSetAttrInt(Op, 'axis', -1); //default
TFE_OpSetAttrType(Op, 'TI', DataType); //indices type
end;
NumOutVals := 1;
try
// **** THIS IS THE ACTUAL CALL TO THE C API, WHERE Op HAS THE OPNAME
TFE_Execute(Op, #OutTensH, #NumOutVals, Status);
// ***********************************************************************
except on e:Exception do
raise Exception.Create('TensorFlow unable to execute ' + OpName +
' operation: ' + e.Message);
end;
if not CheckStatus(Status) then
Exit;
Result := TTensor.CreateWithHandle(OutTensH);
finally
if Assigned(Op) then
TFE_DeleteOp(Op);
TF_DeleteStatus(Status);
{Even if exception occurred, don't want to leave any temps dangling}
if Assigned(Tensor2) and Tensor2.IsTemp then
Tensor2.Free;
if Assigned(Tensor3) and Tensor3.IsTemp then
Tensor3.Free;
if Assigned(Tensor4) and Tensor4.IsTemp then
Tensor4.Free;
if IsTemp then
Free;
end;
end;
In the meantime, I found the description file of TensorFlow at: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/ops/ops.pbtxt. This includes all the operations and their detailed specification.
If someone is interested in a pascal interface to TF, I created one at https://github.com/zsoltszakaly/tensorflowforpascal.
Here is how you can obtain the list of valid operation names from Python:
from tensorflow.python.framework.ops import op_def_registry
registered_ops = op_def_registry.get_registered_ops()
valid_op_names = sorted(registered_ops.keys())
print(len(valid_op_names)) # Number of operation names in TensorFlow 2.0
1223
print(*valid_op_names, sep='\n')
# Abort
# Abs
# AccumulateNV2
# AccumulatorApplyGradient
# AccumulatorNumAccumulated
# AccumulatorSetGlobalStep
# AccumulatorTakeGradient
# Acos
# Acosh
# Add
# ...

uvm_monitor - does not sample correctly. Where am I wrong?

I have the following interface and uvm_monitor (run_phase shown below).
The DUT signals are "x" for sometime. When I print the signals, in my monitor, they are captured as "x". Great.
Next, DUT signals show a valid value (the first time). When I print the signals, in my monitor, they are captured as with valid values. Great.
Next, DUT updates the all the three signals to the next value, and at time stamp 134, mirror_byte_wr_en remains to be 0 but expected to be at 0xffff..
Any idea, why? Appreciate your thoughts and inputs.
Example output from the log:
UVM_INFO snp_decomp_snpd_egress_monitor.sv(65) # 122:
uvm_test_top.m_snp_decomp_env.snpd_egress[0].m_monitor
[snp_decomp_snpd_egress_monitor] mirror_data =
0x00006c61776e694720616669617a7548
UVM_INFO snp_decomp_snpd_egress_monitor.sv(71) # 122:
uvm_test_top.m_snp_decomp_env.snpd_egress[0].m_monitor
[snp_decomp_snpd_egress_monitor] mirror_byte_wr_en = 0xffff
UVM_INFO snp_decomp_snpd_egress_monitor.sv(76) # 122:
uvm_test_top.m_snp_decomp_env.snpd_egress[0].m_monitor
[snp_decomp_snpd_egress_monitor] mirror_wr_addr = 0x00000
UVM_INFO snp_decomp_snpd_egress_monitor.sv(65) # 134:
uvm_test_top.m_snp_decomp_env.snpd_egress[0].m_monitor
[snp_decomp_snpd_egress_monitor] mirror_data =
0x3c10xxxxxxxxxxxxxxxx616c00000000
UVM_INFO snp_decomp_snpd_egress_monitor.sv(71) # 134:
uvm_test_top.m_snp_decomp_env.snpd_egress[0].m_monitor
[snp_decomp_snpd_egress_monitor] mirror_byte_wr_en = 0x0000
UVM_INFO snp_decomp_snpd_egress_monitor.sv(76) # 134:
uvm_test_top.m_snp_decomp_env.snpd_egress[0].m_monitor
[snp_decomp_snpd_egress_monitor] mirror_wr_addr = 0x00010
enter code here
task run_phase(uvm_phase phase);
snp_decomp_snpd_egress_transaction tr;
tr = snp_decomp_snpd_egress_transaction ::type_id::create("tr");
forever begin
#(vif.egress.egress_cb);
fork
begin
// # (vif.egress.egress_cb);
tr.mirror_data = vif.egress.egress_cb.mirror_wr_data;
`uvm_info(get_type_name(),$sformatf("mirror_data = 0x%x\n", vif.egress.egress_cb.mirror_wr_data),UVM_LOW);
end
begin
// # (vif.egress.egress_cb);
tr.mirror_wr_byte_en = vif.egress.egress_cb.mirror_byte_wr_en;
`uvm_info(get_type_name(),$sformatf("mirror_byte_wr_en = 0x%x\n", vif.egress.egress_cb.mirror_byte_wr_en),UVM_LOW);
end
begin
// # (vif.egress.egress_cb);
tr.mirror_wr_addr = vif.egress.egress_cb.mirror_wr_addr;
`uvm_info(get_type_name(),$sformatf("mirror_wr_addr = 0x%x\n", vif.egress.egress_cb.mirror_wr_addr),UVM_LOW);
end
join
end
endtask : run_phase
interface snp_decomp_snpd_egress_intf(input logic clock, input logic reset);
logic [127:0] mirror_wr_data;
logic [15:0] mirror_byte_wr_en;
logic [18:0] mirror_wr_addr;
modport DUT (
input clock,
input reset,
output mirror_wr_data,
output mirror_byte_wr_en,
output mirror_wr_addr
); // modport DUT
clocking egress_cb #(posedge clock);
input mirror_wr_data;
input mirror_byte_wr_en;
input mirror_wr_addr;
endclocking: egress_cb
modport egress(clocking egress_cb);
endinterface : snp_decomp_snpd_egress_intf
enter image description here
It is correct behaviour because sample values in clocking block were taken from the previous clock cycle. It depends on SystemVerilog time step semantics.
begin
#(vif.egress.egress_cb);
`uvm_info(get_type_name(), $sformatf("mirror_byte_wr_en: value from previous cycle - 'h%0h, value from current cycle - 'h%0h",
vif.egress.egress_cb.mirror_byte_wr_en, vif.egress.mirror_byte_wr_en), UVM_LOW)
end
For full understanding - LRM 14.13.
Best regards, Maksim.

How to run a function during a limited time?

I've a function and would like to call here each 2 seconds during 3 seconds.
I tried timer.performwithDelay() but it doesn't answer to my question.
Here is the function I want to call each 2 secondes during 3 seconds :
function FuelManage(event)
if lives > 0 and pressed==true then
lifeBar[lives].isVisible=false
lives = lives - 1
-- print( lifeBar[lives].x )
livesValue.text = string.format("%d", lives)
end
end
How can I use timer.performwithDelay(2000, callback, 1) to call my function FuelManage(event) ?
So it looks like what you are actually after is to start a few check 2 seconds from "now", for a duration of 3 seconds. You can schedule registering and unregistering for the enterFrame events. Using this will call your FuelManage function every time step during the period of interest:
function cancelCheckFuel(event)
Runtime:removeListener('enterFrame', FuelManager)
end
function FuelManage(event)
if lives > 0 and pressed==true then
lifeBar[lives].isVisible=false
lives = lives - 1
-- print( lifeBar[lives].x )
livesValue.text = string.format("%d", lives)
end
end
-- fuel management:
local startFuelCheckMS = 2000 -- start checking for fuel in 2 seconds
local fuelCheckDurationMS = 3000 -- check for 3 seconds
local stopFuelCheckMS = startFuelCheckMS + fuelCheckDurationMS
timer.performWithDelay(
startFuelCheckMS,
function() Runtime:addEventListener('enterFrame', FuelManager) end,
1)
timer.performWithDelay(
stopFuelCheckMS,
function() Runtime:removeEventListener('enterFrame', FuelManager) end,
1)
If this is too high frequency, then you'll want to use a timer, and keep track of time:
local fuelCheckDurationMS = 3000 -- check for 3 seconds
local timeBetweenChecksMS = 200 -- check every 200 ms
local totalCheckTimeMS = 0
local startedChecking = false
function FuelManage(event)
if lives > 0 and pressed==true then
lifeBar[lives].isVisible=false
lives = lives - 1
-- print( lifeBar[lives].x )
livesValue.text = string.format("%d", lives)
end
if totalCheckTimeMS < 3000 then
timer.performWithDelay(timeBetweenChecksMS, FuelManage, 1)
if startedChecking then
totalCheckTimeMS = totalCheckTimeMS + timeBetweenChecksMS
end
startedChecking = true
end
end
-- fuel management:
local startFuelCheckMS = 2000 -- start checking for fuel in 2 seconds
timer.performWithDelay(startFuelCheckMS, FuelManage, 1)
Set a timer inside a timer like this:
function FuelManage(event)
if lives > 0 and pressed==true then
lifeBar[lives].isVisible=false
lives = lives - 1
-- print( lifeBar[lives].x )
livesValue.text = string.format("%d", lives)
end
end
-- Main timer, called every 2 seconds
timer.performwithDelay(2000, function()
-- Sub-timer, called every second for 3 seconds
timer.performwithDelay(1000, FuelManage, 3)
end, 1)
Be careful though because the way it's setup know you will have an infinite number of timer running very soon... Since the first timer has a lower lifetime than the second one. So you might think if you would like to secure the second timer by making sure it's cancelled first before calling it again, this kind of thing.

How to initialize a DT028ATFT display

I am trying to initialize a DT028ATFT-TS display on an STM32F10B main board. The system worked with DT028TFT-TS before, but that display has been discontinued. As a result of using the new diplay, the interface also had to change from ILI9320 to ILI9341. I am now basically trying to initialize the new display in a configuration that would be equivalent to what I had before.
The problem I am facing is that the display image ends up showing horizontal streaks randomly distributed (slightly different at every startup) with a bit of a flicker. And, at times (not sure if related), it just shows the backlight and nothing else - no streaks, no test image. The test image is just one big red square (100x100) displayed at x=100, y=50. You can see the effect of the problem here: Streaked Display Image.
The following is part of the initialization code that I've used - part of it taken as such from DisplayTech's sample code offered on their website, part of it customized. I've excluded commands from the sample code that are not documented under ILI9341 (probably vendor customization) and the gamma correction parameters, just to save some space. Any help in finding out where I went wrong would be appreciated.
// DT028ATFT LCD init - ILI9341:
// Frame Rate Control
SPI_WriteCMD(0xB1);
SPI_WriteDAT(0x00); // division ratio: 1
SPI_WriteDAT(0x10); // 16 clocks per line
// Power Control
SPI_WriteCMD(0xC0);
SPI_WriteDAT(0x25); // GVDD = 4.70V
SPI_WriteCMD(0xC1);
SPI_WriteDAT(0x03); // VCL=VCI x 2, VGH=VCI x 6, VGL=-VCI x 3
// VCOM Control
SPI_WriteCMD(0xC5);
SPI_WriteDAT(0x5C); // VCOMH = 5.000 V
SPI_WriteDAT(0x4C); // VCOML = -0.600 V
SPI_WriteCMD(0xC7);
SPI_WriteDAT(0x94); // VCOMH = VMH - 44, VCOML = VML - 44
// Memory Access Control
SPI_WriteCMD(0x36);
SPI_WriteDAT(0x08); // BGR=1, Normal addr order and refresh direction
// Write CTRL Display
SPI_WriteCMD(0x53);
SPI_WriteDAT(0x24); // BCTRL=1, DD=0, BL=1
// Display Function Control
SPI_WriteCMD(0xB6);
SPI_WriteDAT(0x00); // Normal scan, V63 pos pol / V0 neg pol
SPI_WriteDAT(0xA0); // LCD normally white, G1 to G320, S720 to S1
SPI_WriteDAT(0x27); // NL = 320
SPI_WriteDAT(0x00); // PCDIV not used
// Entry Mode Set
SPI_WriteCMD(0xB7);
SPI_WriteDAT(0x06); // Normal display for G1-G320 output, Low voltage detection enabled
// Column Address Set
SPI_WriteCMD(0x2A);
SPI_WriteDAT(0x00);
SPI_WriteDAT(0x00); // Start Column = 0
SPI_WriteDAT(0x00);
SPI_WriteDAT(0xEF); // End Column = 239
// Page Address Set
SPI_WriteCMD(0x2B);
SPI_WriteDAT(0x00);
SPI_WriteDAT(0x00); // Start Page = 0
SPI_WriteDAT(0x01);
SPI_WriteDAT(0x3F); // End Page = 319
// Gamma Set
SPI_WriteCMD(0x26);
SPI_WriteDAT(0x01); // Gamma Curve 1 selected (G2.2)
// Pixel Format Set
SPI_WriteCMD(0x3A);
SPI_WriteDAT(0x55); // 16bits/pixel (RGB and MCU i/f)
// Interface Control
SPI_WriteCMD(0xF6);
SPI_WriteDAT(0x00); // image data not wrapped around (exceeding data ignored)
SPI_WriteDAT(0x00); // MSB used also as LSB for R and B (64k colours)
SPI_WriteDAT(0x00); // Disp Op Mode: internal clk, GRAM access: Sys I/F, 1 transf/pxl (16bit 64k colours)
// RGB Interface Signal Control
SPI_WriteCMD(0xB0);
SPI_WriteDAT(0xC0); // BypassMode=1, RCM=2, VSPL=0, HSPL=0, DPL=0, EPL=0
// Sleep Mode off (DC/DC conv enabled, internal osc started)
SPI_WriteCMD(0x11);
Dly100us((void*)1200);
// Display ON
SPI_WriteCMD(0x29);
// ===============================
your problem sounds like a timing issue. Have you tried reducing the frame rate? that should relax the display timing. you are setting it to 119 Hz.
are you doing a proper reset before the init?
you can compare with other implementations for the ILI9341 controller:
Example
Atmel Library

Corona SDK array index is beyond array bounds, advice needed

I will try to as concise as possible with my issue.
Firstly, files are:
block.lua
base.lua
main.lua
In block.lua I create a block, add collision detection and a cleanup code.
In base.lua I create a base made up of 4 columns and 10 rows. 40 blocks in total.
In main.lua I create 4 bases made from the base.class.
All is working fine once the game begins.
I remove the bases and call them again on level 2.
They create themselves ok BUT
when the enemy is destroyed once again, and the bases are to be rebuilt, I get an:
array index 1 is beyond array bounds:1..1
-- all the way up to--
array index 800 is beyond array bounds:1..159
it will then create the bases and continue until the enemys are destroyed and do the same again starting at :
array index 800 is beyond array bounds:1..159
-- all the way up to--
array index 4000 is beyond array bounds:1..159
The terminal points me at block.lua line 23
blockGroup:insert(blockNum,self.block)
Now I cant see anything wrong in the class, I have looked and googled for hours but all to no avail.
I would really appreciate a helping hand to guide me here please.
I have tried rewriting the "cleanup" etc but no joy.
I left a few commented out bits in there and removed some of the irrelevant stuff.
I post below the relevant code:
--MAIN.LUA--
function gameOver()
Runtime:removeEventListener("enterFrame", onEnterFrame)
Runtime:removeEventListener("enterFrame", movePlayer)
layers:removeSelf()
layers = nil
enemyCount = 0
for i = 1,#allEnemys do
timer.cancel(allEnemys[i].clock)
Runtime:removeEventListener( "enterFrame", allEnemys[i] )
display.remove(allEnemys[i].image)
allEnemys[i].image=nil
end
allEnemys=nil
cleanupBlocks()
end
----------------------------------------------------------------------
-- LEVEL UP --
----------------------------------------------------------------------
function levelUp(level)
enemyCount = 0
local enemys = require("modules.enemy")
if allEnemys ~= nil then
for i = 1,#allEnemys do
timer.cancel(allEnemys[i].clock)
Runtime:removeEventListener( "enterFrame", allEnemys[i] )
display.remove(allEnemys[i].image)
allEnemys[i].image=nil
end
end
allEnemys=nil
cleanupBlocks()
levels()
end
----------------------------------------------------------------------
-- LEVELS --
----------------------------------------------------------------------
function levels(level)
function createInvader(x, y, row)
for j = 1, 2 do
for i = 1, 2 do
if allEnemys == nil then
allEnemys = {}
else
enemysCount=#allEnemys
end
allEnemys[#allEnemys + 1] = enemys:new()
allEnemys[#allEnemys ]:init(i * 60, j * 70 + 70,j)
allEnemys[#allEnemys ]:start()
end
end
end
createInvader()
--[[function createBases1()
local base = require("modules.base")
for i = 1, 4 do
base:new()
base:init(i * 180 - 130, 850)
end
end ]]--
createBases()
end
--BLOCK.LUA--
local block = {}
local block_mt = { __index = block}
local scene = scene
local blockGroup = display.newGroup()
local blockNum = 0
function block:new() -- constructor
local group = {}
return setmetatable( group, block_mt )
end
function block:init(xloc,yloc) --initializer
-- Create attributes
self.block = display.newRect( xloc,yloc,10,10)
self.block:setFillColor ( 2, 255, 14 )
blockNum = blockNum + 1
blockGroup:insert(blockNum,self.block)
local blockCollisionFilter = { categoryBits = 128, maskBits = 387}
physics.addBody( self.block, "static", {filter = blockCollisionFilter})
self.count = 1
end
function cleanupBlocks()
--[[ print(blockNum, blockGroup.numChildren)
for i=1,blockGroup.numChildren do
blockGroup[1]:removeSelf()
blockGroup[1] = nil
end ]]--
print(blockNum, blockGroup.numChildren)
while blockGroup.numChildren>0 do
display.remove(blockGroup[1])
blockGroup[1]=nil
end
end
function block:start()
--- Create Listeneres
self.block:addEventListener( "collision", self )
scene:addEventListener('base_block_event', self)
end
return block
--BASE.LUA--
local base = {}
local base_mt = { __index = base}
local scene = scene
local block = require("modules.block")
function base:new() -- constructor
local group = {}
return setmetatable( group, base_mt )
end
function base:init(xloc, yloc) --initializer
-- Create attributes
local base
for j = 1, 4 do
for i = 1, 10 do
base = block:new()
base:init(xloc+i * 10,yloc+j * 10)
base:start()
end
end
end
return base
I see you use
blockNum = blockNum + 1
blockGroup:insert(blockNum,self.block)
Try to use
blockGroup:insert(self.block)
just to see if you still get that error.

Resources