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

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.

Related

Face detection using open cv

It uses hog as default model. You can also use cnn for better accuracy but the detection process will be slow.
cascade_classifier = cv2.CascadeClassifier('haarcascades/haarcascade_eye.xml')
cap = cv2.VideoCapture(0)
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
gray = cv2.cvtColor(frame, 0)
detections = cascade_classifier.detectMultiScale(gray,scaleFactor=1.3,minNeighbors=5)
if(len(detections) > 0):
(x,y,w,h) = detections[0]
frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
# for (x,y,w,h) in detections:
# frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
# Display the resulting frame
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()```

using usocket seems to halt the loop (micropython)

I'm trying to code a simple program for a ESP32 board.
My main program is fairly simple and it has to run on a loop.
On the side, the device also needs to be able to respond to HTTP requests with a very simple response.
This is my attempt (a rework of https://randomnerdtutorials.com/micropython-esp32-esp8266-bme280-web-server/):
try:
import usocket as socket
except:
import socket
from micropython import const
import time
REFRESH_DELAY = const(60000) #millisecondi
def do_connect():
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.config(dhcp_hostname=HOST)
wlan.connect('SSID', 'PSWD')
while not wlan.isconnected():
pass
print('network config:', wlan.ifconfig())
import json
import esp
esp.osdebug(None)
import gc
gc.collect()
do_connect()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, SENSOR_SCKT_PORT))
s.listen(5)
prevRun = 0
i = 0
while True:
print("iteration #"+str(i))
i += 1
# run every 60 seconds
curRun = int(round(time.time() * 1000))
if curRun - prevRun >= REFRESH_DELAY:
prevRun = curRun
# MAIN PROGRAM
# ......
# whole bunch of code
# ....
# run continuously:
try:
if gc.mem_free() < 102000:
gc.collect()
conn, addr = s.accept()
conn.settimeout(3.0)
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
conn.settimeout(None)
request = str(request)
#print('Content = %s' % request)
measurements = 'some json stuff'
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.send(measurements)
conn.close()
except OSError as e:
conn.close()
print('Connection closed')
what happens is I only get the iteration #0, and then the while True loop halts.
If I ping this server with a HTTP request, I get a correct response, AND the loop advances to iteration #1 and #2 (no idea why it thinks I pinged it with 2 requests).
So it seems that socket.listen(5) is halting the while loop.
Is there any way to avoid this?
Any other solution?
I don't think that threading is an option here.
The problem is that s.accept() is a blocking call...it won't return until it receives a connection. This is why it pauses your loop.
The easiest solution is probably to check whether or not a connection is waiting before calling s.accept(); you can do this using either select.select or select.poll. I prefer the select.poll API, which would end up looking something like this:
import esp
import gc
import json
import machine
import network
import select
import socket
import time
from micropython import const
HOST = '0.0.0.0'
SENSOR_SCKT_PORT = const(1234)
REFRESH_DELAY = const(60000) # milliseconds
def wait_for_connection():
print('waiting for connection...')
wlan = network.WLAN(network.STA_IF)
while not wlan.isconnected():
machine.idle()
print('...connected. network config:', wlan.ifconfig())
esp.osdebug(None)
gc.collect()
wait_for_connection()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, SENSOR_SCKT_PORT))
s.listen(5)
poll = select.poll()
poll.register(s, select.POLLIN)
prevRun = 0
i = 0
while True:
print("iteration #"+str(i))
i += 1
# run every 60 seconds
curRun = int(round(time.time() * 1000))
if curRun - prevRun >= REFRESH_DELAY:
prevRun = curRun
# MAIN PROGRAM
# ......
# whole bunch of code
# ....
# run continuously:
try:
if gc.mem_free() < 102000:
gc.collect()
events = poll.poll(100)
if events:
conn, addr = s.accept()
conn.settimeout(3.0)
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
conn.settimeout(None)
request = str(request)
# print('Content = %s' % request)
measurements = 'some json stuff'
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.send(measurements)
conn.close()
except OSError:
conn.close()
print('Connection closed')
You'll note that I've taken a few liberties with your code to get it running on my device and to appease my sense of style; primarily, I've excised most of your do_connect method and put all the imports at the top of the file.
The only real changes are:
We create a select.poll() object:
poll = select.poll()
We ask it to monitor the s variable for POLLIN events:
poll.register(s, select.POLLIN)
We check if any connections are pending before attempting to handle a connection:
events = poll.poll(100)
if events:
conn, addr = s.accept()
conn.settimeout(3.0)
[...]
With these changes in place, running your code and making a request looks something like this:
iteration #0
iteration #1
iteration #2
iteration #3
iteration #4
iteration #5
iteration #6
Got a connection from ('192.168.1.169', 54392)
iteration #7
iteration #8
iteration #9
iteration #10
Note that as written here, your loop will iterate at least once every 100ms (and you can control that by changing the timeout on our call to poll.poll()).
Note: the above was tested on an esp8266 device (A Wemos D1 clone) running MicroPython v1.13-268-gf7aafc062).

how to receive data from mqtt and open cv video stream at the same time

My project need to receive mqtt data and videostream data at the same time. However, when my raspi receiving video data by open cv, it cant receive iOT data at the same time.
My raspi need to check if the iot data is on, and the video will not turn on and receive data.
So the piority is
iOT sensor check if there is something detected-----> video will not turn. (case 1)
iOT sensor check if there is nothing detected-------> video turn on and receive another image data.
[Update 2]
# import the necessary packages
from collections import deque
from imutils.video import VideoStream
import numpy as np
import argparse
import cv2
import imutils
import time
import serial
import struct
import paho.mqtt.client as mqtt
#subscribe mqtt publisher with topic "esp/pot"
def on_connect(client, userdata,flags, rc):
client.subscribe("/esp/pot")
#get the data from the publisher and save to integer variable "bdy"
def on_message(client, userdata, msg):
bdy=int(msg.payload)
#when disconnect stop the loop of mqtt function
def on_disconnect(client, userdata,rc=0):
client.loop_stop()
#Assign the mqtt client as client
client = mqtt.Client()
#Assign the mqtt connect function to client connect
client.on_connect = on_connect
#Assign the mqtt message function to client message
client.on_message = on_message
#set the client connect to local broker host
client.connect("localhost", 1883, 60) # localhost is the Raspberry Pi itself
#Below is setting up the OpenCV function
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
#get the video if path provided
ap.add_argument("-v", "--video",
help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=0,
help="max buffer size")
args = vars(ap.parse_args())
# define detect object, in here is a green object
# define the lower and upper boundaries of the "green" color in HSV value
# ball in the HSV colorspace, then initialize the
# list of tracked points
greenLower = (25, 96, 49)
greenUpper = (39, 255, 255)
Lower = greenLower
Upper = greenUpper
#define the trace point of the object detected, here is centroid
pts = deque(maxlen=args["buffer"])
#setup the serial port for arduino, which is for another motor control
ser = serial.Serial('/dev/ttyUSB0',9600)
# if a video path was not supplied, grab the reference
# to the webcam (we use webcam in this project
if not args.get("video", False):
vs = VideoStream(src=0).start()
# otherwise, grab a reference to the video file
else:
vs = cv2.VideoCapture(args["video"])
# allow the camera or video file to warm up
time.sleep(2.0)
#initialize the integer variable "bdy" to zero
bdy = 0
# main function body, keep looping
while True:
# grab the current frame of the webcam
frame = vs.read()
# handle the frame from VideoCapture or VideoStream
frame = frame[1] if args.get("video", False) else frame
# if we are viewing a video and we did not grab a frame,
# then we have reached the end of the video
if frame is None:
break
# resize the frame, blur it, and convert it to the HSV
# color space
frame = imutils.resize(frame, width=246)
blurred = cv2.GaussianBlur(frame, (11, 11), 0)
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
# construct a mask for the color "green", then perform
# a series of dilations and erosions to remove any small
# blobs left in the mask
mask = cv2.inRange(hsv, Lower, Upper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
# find contours in the mask and initialize the current
# (x, y) center of the green object
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
#initial center value
center = None
#start mqtt client loop function for receiving data from broker, int variable "bdy"
client.loop_start()
#if the data from broker is not 1
if bdy != 1:
#printout bdy value for debug
print (bdy)
# only proceed if at least one contour of green object was found
if len(cnts) > 0:
# find the largest contour in the mask, then use
# it to compute the minimum enclosing circle and
# centroid
c = max(cnts, key=cv2.contourArea)
#save webcam detected object centroid to cX and cY
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
#locate the centre of the green object
center = (cX, cY)
# only proceed if the radius of the detected green object meets a minimum size,
# say radius >2 to remove unneccssary noise
if radius > 2:
# draw the circle and centroid on the frame,
# then update the list of tracked points
#cv2.circle(frame, (int(x), int(y)), int(radius),
#(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
# print x_position
print (cX)
# send the cX value to the arduino by serial port with braud rate 9600
ser.write(struct.pack('>H', cX))
# if the data from broker is not 1,
# here the broker actually just send data from sensor with digital value
# so it should be 0
else:
print("boundary detected")
#stop the client loop function from receive data for clearing the retain messsage
client.loop_stop()
# show the frame from webcam to raspberry pi screen for debug
cv2.imshow("Frame", frame)
#awaiting user press key for action
chkKey = cv2.waitKey(1) & 0xFF
# if the 'q' key is pressed, stop the main function body "while True loop"
if chkKey == ord("q"):
break
# if we are not using a video file, stop the camera video stream
if not args.get("video", False):
vs.stop()
# otherwise, release the camera
else:
vs.release()
# close all windows
cv2.destroyAllWindows()
#stop the client loop function
client.loop_stop()

Verilog - digital clock- Minute doesnt work

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

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

Resources