#1: if varsa else de olmalıdır
Verilog ile sayısal tasarım tarifi yaparken, if bloğu koyduğunuzda else bloğu koymanız faydalıdır. Bu sayede if bloğunda tanımladığınız durumlar dışında da ne beklediğinizi net bir biçimde sentezleme aracına belirtmiş olursunuz, sizin açınızdan da durum net olur.

Şu şekilde tanım yapmak yerine:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_r <= 8'h00;
	end
	else begin
		if(in_sinyal == 2'b01) begin
			yazmacim_r <= 8'h06;
		end
		else if(in_sinyal == 2'b10) begin
			yazmacim_r <= 8'h42;
		end
	end
end

Şöyle bir tanım yapmak daha yerinde olacaktır:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_r <= 8'h00;
	end
	else begin
		if(in_sinyal == 2'b01) begin
			yazmacim_r <= 8'h06;
		end
		else if(in_sinyal == 2'b10) begin
			yazmacim_r <= 8'h42;
		end
		else begin
			yazmacim_r <= yazmacim_r;
		end
	end
end

Bu sayede in_sinyal için 2’b11 ve 2’b00 durumlarında yazmacim_r yazmacının değerinin korunması gerektiğini de açık olarak belirttik. Bariz noktalar için fazlaca kod yazılmış gibi gelebilir, fakat sürprizlerle karşılaşma ihtimali azalacaktır. Belki de yukarıdaki örnekte 2’b11 durumunda yazmacim_r yazmacını kendisine eşitlemek istemiyordunuz, ama unuttunuz, bu ifade şekli bu durumları daha net karşınıza çıkarmaktadır.

#2: if/else blokları tek satır da olsa begin/end içerisinde gruplanmalıdır
İçerisinde tek satır ifadeleriniz olsa bile if ve else bloklarınızın çevresini begin/end ile sarmanız ileride hata yapmanızı önleyecektir. Benzer şekilde tasarımınızı daha okunaklı hale getirerek bakımını da kolaylaştıracaktır.

Şu kodu inceleyelim:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_r 	<= 8'h00;
		yazmacim2_r <= 32'h07070707;
        end
	else begin
		if(in_sinyal == 2'b01) 
			yazmacim_r <= 8'h06;
		else if(in_sinyal == 2'b10) 
			yazmacim_r <= 8'h42;
		else 
			yazmacim_r <= yazmacim_r;
			yazmacim2_r <= yazmacim2_r;
	end
end

yazmacim2_r yazmacının tam ne olduğu belli değil gibi değil mi? Bir de şu koda bakalım:

always @ (posedge in_clock) begin
if(!in_reset) begin
yazmacim_r 	<= 8'h00;
yazmacim2_r <= 32'h07070707;
end
else begin
if(in_sinyal == 2'b01) 
yazmacim_r <= 8'h06;
else if(in_sinyal == 2'b10) 
yazmacim_r <= 8'h42;
else 
yazmacim_r <= yazmacim_r;
yazmacim2_r <= yazmacim2_r;
end
end

Her şey aynı, sadece satır aralıkları kaldırıldı, çok daha karışık. Bunun yerine şu yazım tarzı her şeyi daha net yapacaktır:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_r 	<= 8'h00;
		yazmacim2_r <= 32'h07070707;
        end
	else begin
		if(in_sinyal == 2'b01) begin
			yazmacim_r <= 8'h06;
		end
		else if(in_sinyal == 2'b10)  begin
			yazmacim_r <= 8'h42;
		end
		else begin
			yazmacim_r <= yazmacim_r;
		end
		yazmacim2_r <= yazmacim2_r;
	end
end

Bu tarz basit tasarımlarda çok da önemli gelmeyebilir, fakat daha kapsamlı tasarımlarda anlaşılabilirliği arttıracaktır. Bu örnek aslında kendi içerisinde yazmacim2_r yazmacının tanımı nedeniyle sorunlu (bir sonraki maddede bu sorunu ele alıyoruz), fakat maddenin amacını güzel anlatıyor.

#3: İç içe if/else bloklarında değer atamaları yapılıyorsa, mümkünse her bir if/else içerisinde net olarak değer ataması durumu belirtilmelidir
Bir üstteki örneği tekrar ele alalım:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_r 	<= 8'h00;
		yazmacim2_r <= 32'h07070707;
        end
	else begin
		if(in_sinyal == 2'b01) begin
			yazmacim_r <= 8'h06;
		end
		else if(in_sinyal == 2'b10)  begin
			yazmacim_r <= 8'h42;
		end
		else begin
			yazmacim_r <= yazmacim_r;
		end
		yazmacim2_r <= yazmacim2_r;
	end
end

Bu kod bloğu ile yazmacim2_r yazmacının aslında her durumda kendisine eşit olduğunu bildiriyoruz, yani bir bakıma statik bir ROM değeri tanımlıyoruz. Peki bu durumda yazmacim2_r yazmacı in_sinyal girdisinden bağımsız bir yazmaç değil midir? Neden birbirinden bağımsız sinyalleri sanal olarak aynı kod bloğunda tanımlayarak anlaşılabilirliği öldürüyoruz? Bunun yerine şu yazım tarzını tercih etsek her şey daha anlaşılır olacaktır:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_r 	<= 8'h00;
        end
	else begin
		if(in_sinyal == 2'b01) begin
			yazmacim_r <= 8'h06;
		end
		else if(in_sinyal == 2'b10)  begin
			yazmacim_r <= 8'h42;
		end
		else begin
			yazmacim_r <= yazmacim_r;
		end
	end
end

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim2_r <= 32'h07070707;
        end
	else begin
		yazmacim2_r <= yazmacim2_r;
	end
end

Bu şekilde herkes rahatlıkla yazmacim2_r yazmacının in_sinyal ve yazmacim_r‘dan bağımsız olduğunu görebiliyor.

Başka bir açıdan sorunu ele alabilmek için şu durumu ele alalım:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_r 	<= 8'h00;
		yazmacim2_r <= 32'h07070707;
	end
	else if(in_sinyal2 == 2'b01) begin
		yazmacim_r 	<= yazmacim_r + 1;
		yazmacim2_r <= 32'hFB070707;
	end
	else begin
		if(in_sinyal == 2'b01) begin
			yazmacim_r <= 8'h06;
		end
		else if(in_sinyal == 2'b10)  begin
			yazmacim_r <= 8'h42;
		end
		else begin
			yazmacim_r <= yazmacim_r;
		end
		yazmacim2_r <= yazmacim2_r;
	end
end

Bu örnekte yazmacim_r ile yazmacim2_r‘ı bir bakımı aynı blokta ele almayı bir nebze geçerli kılmaya çalıştık. Burada da anlaşılabilirliği zorlaştırmış olduk, bunun yerine şu yazım şekli daha doğru olacaktır:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_r 	<= 8'h00;
		yazmacim2_r <= 32'h07070707;
	end
	else if(in_sinyal == 2'b00) begin
		yazmacim_r 	<= yazmacim_r + 1;
		yazmacim2_r <= 32'hFB070707;
	end
	else begin
		if(in_sinyal == 2'b01) begin
			yazmacim_r <= 8'h06;
			yazmacim2_r <= yazmacim2_r;
		end
		else if(in_sinyal == 2'b10)  begin
			yazmacim_r <= 8'h42;
			yazmacim2_r <= yazmacim2_r;
		end
		else begin
			yazmacim_r <= yazmacim_r;
			yazmacim2_r <= yazmacim2_r;
		end
	end
end

Fakat “hayır, ben yazmacim2_r‘ı in_sinyal‘den bağımsız olarak tanımlamak istiyorum, böyle neden yazayım, saçma!” diyorsanız, doğrusu şu olurdu:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_r 	<= 8'h00;
	end
	else begin
		if(in_sinyal == 2'b00) begin
			yazmacim_r <= yazmacim_r + 1;
		end
		else (in_sinyal == 2'b01) begin
			yazmacim_r <= 8'h06;
		end
		else if(in_sinyal == 2'b10)  begin
			yazmacim_r <= 8'h42;
		end
		else begin
			yazmacim_r <= yazmacim_r;
		end
	end
end

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim2_r <= 32'h07070707;
	end
	else if(in_sinyal == 2'b00) begin
		yazmacim2_r <= 32'hFB070707;
	end
	else begin
		yazmacim2_r <= yazmacim2_r;
	end
end

Hatta böyle bir niyetiniz varsa sentez aracının bu 2 kod bloğunun tarif ettiği elektronik devreyi daha rahat optimize etmesini sağlamak için şöyle bir iyileştirme de yapabilirsiniz:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		sinyal_buffer_1_r 	<= 1'b0;
	end
	else begin
		sinyal_buffer_1_r <= in_sinyal;
	end
end

always @ (posedge in_clock) begin
	if(!in_reset) begin
		sinyal_buffer_2_r 	<= 1'b0;
	end
	else begin
		sinyal_buffer_2_r <= in_sinyal;
	end
end

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_r 	<= 8'h00;
	end
	else begin
		if(sinyal_buffer_1_r == 2'b00) begin
			yazmacim_r <= yazmacim_r + 1;
		end
		else (sinyal_buffer_1_r == 2'b01) begin
			yazmacim_r <= 8'h06;
		end
		else if(sinyal_buffer_1_r == 2'b10)  begin
			yazmacim_r <= 8'h42;
		end
		else begin
			yazmacim_r <= yazmacim_r;
		end
	end
end

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim2_r <= 32'h07070707;
	end
	else if(sinyal_buffer_2_r == 2'b00) begin
		yazmacim2_r <= 32'hFB070707;
	end
	else begin
		yazmacim2_r <= yazmacim2_r;
	end
end

Kontrol girişlerini iki ayrı bufferla bufferlayarak devre bloklarının birbirinden daha uzaklara konabilmesini sağlayabilirsiniz, zamanlamalar daha rahat tutturulacaktır.

#4: if/else bloklarından birinde bir yazmaç/registera bir değer atandıysa, diğerlerinde de bir değer atanmalıdır
Bu sayede her durumu değerlendirdiğiniz net bir biçimde ortaya çıkacak, genel kural olarak uyguladığınızda herhangi bir durumu unutmadığınız belli olacak ve sentezleme aracının tam olarak istediğiniz şekilde sentezlemesini sağlayabileceksiniz. Örnekleyelim:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_1_r 	<= 8'h00;
		yazmacim_3_r 	<= 8'h00;
	end
	else begin
		if(fsm_control_r == 3'b000) begin
			yazmacim_1_r 	<= yazmacim_1_r + 1;
			yazmacim_3_r 	<= 8'h42;
			yazmacim_2_r 	<= 8'h06;
		end
		else (fsm_control_r == 3'b001) begin
			yazmacim_1_r 	<= 8'h06;
			yazmacim_2_r 	<= 8'h08;
		end
		else if(fsm_control_r == 3'b010)  begin
			yazmacim_1_r 	<= 8'h42;
			yazmacim_3_r 	<= 8'h02;
		end
		else if(fsm_control_r == 3'b100)  begin
			yazmacim_1_r 	<= 8'h42;
			yazmacim_3_r 	<= 8'h03;
			yazmacim_2_r 	<= 8'h05;
		end
		else begin
			yazmacim_1_r 	<= yazmacim_1_r;
			yazmacim_3_r 	<= 8'h00;
		end
	end
end

Tasarımı yerine aşağıdaki tasarım daha anlaşılabilir olacaktır:

always @ (posedge in_clock) begin
	if(!in_reset) begin
		yazmacim_1_r 	<= 8'h00;
		yazmacim_2_r 	<= 8'h55;
		yazmacim_3_r 	<= 8'h00;
	end
	else begin
		if(fsm_control_r == 3'b000) begin
			yazmacim_1_r 	<= yazmacim_1_r + 1;
			yazmacim_2_r 	<= 8'h06;
			yazmacim_3_r 	<= 8'h42;
		end
		else (fsm_control_r == 3'b001) begin
			yazmacim_1_r 	<= 8'h06;
			yazmacim_2_r 	<= 8'h08;
			yazmacim_3_r 	<= yazmacim_3_r;
		end
		else if(fsm_control_r == 3'b010)  begin
			yazmacim_1_r 	<= 8'h42;
			yazmacim_2_r 	<= yazmacim_2_r;
			yazmacim_3_r 	<= 8'h02;
		end
		else if(fsm_control_r == 3'b100)  begin
			yazmacim_1_r 	<= 8'h42;
			yazmacim_2_r 	<= 8'h05;
			yazmacim_3_r 	<= 8'h03;
		end
		else begin
			yazmacim_1_r 	<= yazmacim_1_r;
			yazmacim_2_r 	<= yazmacim_2_r;
			yazmacim_3_r 	<= 8'h00;
		end
	end
end

Her durumda neyin ne olması gerektiği açıkça ortada.

Umarım öneriler işinize yarar, iyi tasarımlar.