<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ro">
	<id>http://wiki.dcae.pub.ro/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zhascsi</id>
	<title>WikiLabs - Contribuții utilizator [ro]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.dcae.pub.ro/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zhascsi"/>
	<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php/Special:Contribu%C8%9Bii/Zhascsi"/>
	<updated>2026-10-05T10:47:14Z</updated>
	<subtitle>Contribuții utilizator</subtitle>
	<generator>MediaWiki 1.35.14</generator>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Arhitectura_Sistemelor_de_Calcul&amp;diff=8383</id>
		<title>Arhitectura Sistemelor de Calcul</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Arhitectura_Sistemelor_de_Calcul&amp;diff=8383"/>
		<updated>2026-09-29T08:43:59Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# [[Laboratorul 1]]&lt;br /&gt;
# [[Laboratorul 2]]&lt;br /&gt;
# [[Laboratorul 4]]&lt;br /&gt;
# [[Laboratorul 6]]&lt;br /&gt;
&lt;br /&gt;
== Tutoriale ==&lt;br /&gt;
&lt;br /&gt;
[[Tutorial Vivado]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--[https://wiki.dcae.pub.ro/images/8/89/QuartusNewProjectTutorial.pdf Quartus New Project Tutorial]--&amp;gt;&lt;br /&gt;
[http://www.emmelmann.org/Library/Tutorials/docs/verilog_ref_guide/vlog_ref_top.html Verilog Quick Reference Guide]&lt;br /&gt;
&lt;br /&gt;
[https://chipverify.com/systemverilog/systemverilog-quick-refresher SystemVerilog Quick Refresher]&lt;br /&gt;
&lt;br /&gt;
== Suport software ==&lt;br /&gt;
&lt;br /&gt;
=== Xilinx ===&lt;br /&gt;
[[Tutorial instalare Vivado]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=== Intel ===&lt;br /&gt;
[http://fpgasoftware.intel.com/14.1/?edition=web&amp;amp;platform=windows&amp;amp;download_manager=dlm3 Quartus II Web Edition 14.1].&lt;br /&gt;
&lt;br /&gt;
(Pentru o instalare minimală selectați doar Cyclone V din lista de familii FPGA suportate)&lt;br /&gt;
&lt;br /&gt;
Pentru a seta calea simulatorului Modelsim pentru Quartus Lite 18.1 din meniul Tools -&amp;gt; Options ... -&amp;gt; EDA Tool Options se alege pentru ModelSim Altera calea&lt;br /&gt;
/opt/intelFPGA_lite/18.1/modelsim_ase/bin&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== [http://users.dcae.pub.ro/~zhascsi/exam/asc/asc_1.pdf colocviu] ==&lt;br /&gt;
&lt;br /&gt;
== [http://users.dcae.pub.ro/~zhascsi/exam/asc/part.txt refacere partial] ==&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Arhitectura_Sistemelor_de_Calcul&amp;diff=8382</id>
		<title>Arhitectura Sistemelor de Calcul</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Arhitectura_Sistemelor_de_Calcul&amp;diff=8382"/>
		<updated>2026-09-29T08:39:55Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# [[Laboratorul 1]]&lt;br /&gt;
# [[Laboratorul 2]]&lt;br /&gt;
# [[Laboratorul 4]]&lt;br /&gt;
# [[Laboratorul 6]]&lt;br /&gt;
&lt;br /&gt;
== Tutoriale ==&lt;br /&gt;
&lt;br /&gt;
[[Tutorial Vivado]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--[https://wiki.dcae.pub.ro/images/8/89/QuartusNewProjectTutorial.pdf Quartus New Project Tutorial]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://www.emmelmann.org/Library/Tutorials/docs/verilog_ref_guide/vlog_ref_top.html Verilog Quick Reference Guide]&lt;br /&gt;
&lt;br /&gt;
== Suport software ==&lt;br /&gt;
&lt;br /&gt;
=== Xilinx ===&lt;br /&gt;
[[Tutorial instalare Vivado]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=== Intel ===&lt;br /&gt;
[http://fpgasoftware.intel.com/14.1/?edition=web&amp;amp;platform=windows&amp;amp;download_manager=dlm3 Quartus II Web Edition 14.1].&lt;br /&gt;
&lt;br /&gt;
(Pentru o instalare minimală selectați doar Cyclone V din lista de familii FPGA suportate)&lt;br /&gt;
&lt;br /&gt;
Pentru a seta calea simulatorului Modelsim pentru Quartus Lite 18.1 din meniul Tools -&amp;gt; Options ... -&amp;gt; EDA Tool Options se alege pentru ModelSim Altera calea&lt;br /&gt;
/opt/intelFPGA_lite/18.1/modelsim_ase/bin&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== [http://users.dcae.pub.ro/~zhascsi/exam/asc/asc_1.pdf colocviu] ==&lt;br /&gt;
&lt;br /&gt;
== [http://users.dcae.pub.ro/~zhascsi/exam/asc/part.txt refacere partial] ==&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Laboratorul_6&amp;diff=8381</id>
		<title>Laboratorul 6</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Laboratorul_6&amp;diff=8381"/>
		<updated>2026-09-29T08:36:56Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Pipeline cu avansarea datelor ==&lt;br /&gt;
&lt;br /&gt;
Procesorul implementat in laboratorul 4 are numai trei etaje pipeline. Singura dependență de date ce poate apare este cea de tip RAW între instrucțiunea aflată în etapa de EXECUTE și instrucțiunea imediat următoare din etapa de READ, dacă aceasta din urmă folosește rezultatul primeia. Pentru evitarea hazardului de date este necesară gestiunea dependențelor de tip RAW. În laboratorul 4 dependența se elimina din program prin adăugarea unei instrucțiuni NOP între cele două instrucțiuni ce depind una de alta. Această metodă simplă lungește timpul de execuție al programului. Alternativa avansării datelor elimină acest neajuns, dar necesită detecția și gestiunea în HW a dependențelor. Calea de avansare permite citirea operandului direct de la instrucțiunea precedentă, de la ieșirea nivelului EXECUTE.&lt;br /&gt;
 &lt;br /&gt;
[[Fișier: asc_lab5_procesor_fw.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Detecția dependențelor RAW ===&lt;br /&gt;
&lt;br /&gt;
Dependența de date de tip RAW poate apare numai între instrucțiunea aflată în execuție și instrucțiunea următoare, aflată în faza de citire, dacă rezultatul primeia este folosit ca operand de instrucțiunea imediat următoare, adică registrul destinație al primeia coincide cu unul din registrele sursă ale instrucțiunii următoare. Detecția dependenței se face comparând adresa destinație a instrucțiunii din etapa de execuție cu adresele sursă ale instrucțiunii aflate în etapa de citire.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab5_pipeline_fw_cmp.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rezultatul comparării este însă validat numai dacă instrucțiunea aflată în execuție trebuie să scrie în registrul destinație (adică dacă &amp;#039;&amp;#039;&amp;#039;regs_wen&amp;#039;&amp;#039;&amp;#039; este activ) și numai dacă instrucțiunea aflată în READ citește din registrul sursă. Instrucțiunile &amp;#039;&amp;#039;ADD&amp;#039;&amp;#039;, &amp;#039;&amp;#039;SUB&amp;#039;&amp;#039;, &amp;#039;&amp;#039;LOAD&amp;#039;&amp;#039; și &amp;#039;&amp;#039;STORE&amp;#039;&amp;#039; citesc operandul 1 din registre, iar operandul 2 este citit numai de instrucțiunile &amp;#039;&amp;#039;ADD&amp;#039;&amp;#039;, &amp;#039;&amp;#039;SUB&amp;#039;&amp;#039; și &amp;#039;&amp;#039;STORE&amp;#039;&amp;#039;.&lt;br /&gt;
Așadar logica de generare a semnalului &amp;#039;&amp;#039;&amp;#039;fw1&amp;#039;&amp;#039;&amp;#039; poate fi descrisă astfel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
           //                                                      ADD                      SUB                      LOAD                     STORE&lt;br /&gt;
assign fw1 = (r2_dest == r1_sursa1) &amp;amp; regs_wen &amp;amp; ((r1_opcode == 4&amp;#039;b0001) | (r1_opcode == 4&amp;#039;b0010) | (r1_opcode == 4&amp;#039;b1001) | (r1_opcode == 4&amp;#039;b1010));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În mod asemănător se descrie generarea semnalului &amp;#039;&amp;#039;&amp;#039;fw2&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fw2 =               // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Avansarea rezultatului ===&lt;br /&gt;
&lt;br /&gt;
Odată detectată dependența RAW, rezultatul instrucțiunii din etapa de execuție este selectat ca operand în locul valorii registrului sursă.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab5_pipeline_fw_mux.png]]&lt;br /&gt;
&lt;br /&gt;
Dacă &amp;#039;&amp;#039;&amp;#039;fw1&amp;#039;&amp;#039;&amp;#039; este activ, se selectează pentru operandul 1 rezultatul de la ieșirea nivelului de execuție. Analog se face selecția pentru operandul 2:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign operand1 = fw1 ? result : rdata1;&lt;br /&gt;
assign operand2 = (r1_opcode == 4&amp;#039;b1000) ? r1_instr_data : fw2 ?             // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rularea unui program cu dependențe de date ===&lt;br /&gt;
&lt;br /&gt;
Pentru testarea calculatorului se modifică programul anterior eliminând instrucțiunile NOP dintre instrucțiunile ce folosesc una rezultatul alteia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
  0   LOADC R0 #255&lt;br /&gt;
  1   LOADC R1 #254&lt;br /&gt;
  2   LOADC R2 #253&lt;br /&gt;
  3   LOAD  R4 R0&lt;br /&gt;
  4   LOAD  R5 R1&lt;br /&gt;
  5   ADD   R6 R5 R4&lt;br /&gt;
  6   STORE R2 R6&lt;br /&gt;
  7   HALT&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Salturi în pipeline ==&lt;br /&gt;
&lt;br /&gt;
Procesarea instrucțiunilor de salt în pipeline necesită detecția și gestionarea dependețelor de control deoarece decizia de execuție sau nu a salturilor are loc într-una din etapele de procesare ulterioare extragerii instrucțiunii. Pipeline-ul simplu din Laboratorul 4 va executa instrucțiunea de salt în etapa de execuție. La sfârșitul etapei de execuție a instrucțiunii de salt (pe frontul de ceas) contorul de program se încarcă cu adresa de salt iar instrucțiunile ce au intrat sau intră în pipeline după instrucțiunea de salt sunt anulare, înlocuindu-se cu instrucțiuni &amp;#039;&amp;#039;NOP&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab5_procesor_jmp.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În acest laborator setul simplu de instrucțiuni RISC se va completa cu o instrucțiune de salt necondiționată la o adresă specificată în corpul instrucțiunii, &amp;#039;&amp;#039;JMP #target&amp;#039;&amp;#039;.&lt;br /&gt;
Codul instrucțiunii de salt se alege &amp;#039;b1100, iar adresa de salt ocupă octetul inferior al instrucțiunii (la fel ca și constanta instrucțiunii &amp;#039;&amp;#039;LOADC&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Detecția dependenței de control ===&lt;br /&gt;
&lt;br /&gt;
Constă în detecția instrucțiunii de salt în etapa de execuție. Instrucțiunea de salt nu scrie nimic în setul de registre și nici în memorie. Logica de generare a semnalelor &amp;#039;&amp;#039;regs_wen&amp;#039;&amp;#039; și &amp;#039;&amp;#039;write&amp;#039;&amp;#039; trebuie să genereze 0 dacă instrucțiunea curentă din execuție este &amp;#039;&amp;#039;JMP&amp;#039;&amp;#039;.&lt;br /&gt;
Nivelul de execuție se completează cu logica generării semnalului de control &amp;#039;&amp;#039;pc_load &amp;#039;&amp;#039; ce va determina actualizarea PC și înlocuirea cu &amp;#039;&amp;#039;NOP&amp;#039;&amp;#039; a instrucțiunilor mai noi ce deja au intrat în pipeline:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign pc_load = r2_opcode == 4&amp;#039;b1100;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Actualizarea stării procesorului ===&lt;br /&gt;
&lt;br /&gt;
La execuția instrucțiunii &amp;#039;&amp;#039;JMP&amp;#039;&amp;#039; contorul de program, PC, se va încărca cu adresa de salt. Descrierea PC din laboratorul precedent se completează cu o ramură corespunzătoare condiționată de semnalul &amp;#039;&amp;#039;&amp;#039;pc_load &amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(rst)&lt;br /&gt;
        pc &amp;lt;= 0;&lt;br /&gt;
    else if(halt)&lt;br /&gt;
        pc &amp;lt;= pc;&lt;br /&gt;
    else if(pc_load )&lt;br /&gt;
        pc &amp;lt;= pc_target;&lt;br /&gt;
    else &lt;br /&gt;
        pc &amp;lt;= pc + 1;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adresa de salt este byte-ul inferior al instrucțiunii. Când instrucțiunea de salt ajunge în nivelul de execuție, byte-ul inferior este accesibil ca operand 2:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign pc_target = r2_operand2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De asemenea, pentru ca acest byte să ajungă în întregime ca operand 2 în execuție, operandul 2 al instrucțiunii &amp;#039;&amp;#039;JMP&amp;#039;&amp;#039; trebuie selectat în etapa READ la fel cum este selectat acesta pentru instrucțiunea &amp;#039;&amp;#039;LOADC&amp;#039;&amp;#039;. Codul de selecție se modifică astfel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign operand2 = ((r1_opcode == 4&amp;#039;b1000) | (r1_opcode == 4&amp;#039;b1100)) ? r1_instr_data : rdata2; // LOADC sau JMP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
La sfârșitul execuției instrucțiunii de salt, instrucțiunile mai noi ce sunt deja în nivelurile inferioare de pipeline se înlocuiesc cu instrucțiuni &amp;#039;&amp;#039;NOP&amp;#039;&amp;#039;. Astfel registrul pipeline R1 se va încărca cu instrucțiunea &amp;#039;&amp;#039;NOP&amp;#039;&amp;#039; (ce are codul binar &amp;#039;b0000) dacă semnalul de control &amp;#039;&amp;#039;&amp;#039;pc_load &amp;#039;&amp;#039;&amp;#039; este activ:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(rst)&lt;br /&gt;
        r1 &amp;lt;= 0;&lt;br /&gt;
    else if(halt)&lt;br /&gt;
        r1 &amp;lt;= r1;&lt;br /&gt;
    else if(pc_load )&lt;br /&gt;
        r1 &amp;lt;= 0;&lt;br /&gt;
    else&lt;br /&gt;
        r1 &amp;lt;= instr;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Analog se completează și descrierea registrului pipeline R2.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab5_pipeline_jmp.png]]&lt;br /&gt;
&lt;br /&gt;
=== Rularea unui program cu instrucțiuni de salt ===&lt;br /&gt;
&lt;br /&gt;
Pentru testarea calculatorului se modifică programul din memoria de program astfel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
  0   LOADC R0 #255&lt;br /&gt;
  1   LOADC R1 #254&lt;br /&gt;
  2   LOADC R2 #253&lt;br /&gt;
  3   JMP   #7&lt;br /&gt;
  4   ADD   R6 R5 R4&lt;br /&gt;
  5   STORE R2 R6&lt;br /&gt;
  6   HALT&lt;br /&gt;
  7   LOAD  R4 R0&lt;br /&gt;
  8   LOAD  R5 R1&lt;br /&gt;
  9   JMP   #4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Activități suplimentare ==&lt;br /&gt;
&lt;br /&gt;
=== Activitatea 1 ===&lt;br /&gt;
&lt;br /&gt;
Implementați o instrucțiune de salt condiționată, &amp;#039;&amp;#039;JMPZ #target&amp;#039;&amp;#039;. Saltul se va executa (&amp;#039;&amp;#039;&amp;#039;pc_load &amp;#039;&amp;#039;&amp;#039; va fi activat) numai dacă registrul indicator Z (actualizat după execuția instrucțiunii precedente) este 1. Procesorul pipeline se va completa cu un registru pentru indicatori actualizat pe ceas ce salvează în permanență indicatorii (&amp;#039;&amp;#039;&amp;#039;flags&amp;#039;&amp;#039;&amp;#039;) de la ieșirea ALU. Codul instrucțiunii &amp;#039;&amp;#039;JMPZ&amp;#039;&amp;#039; se alege &amp;#039;b1101.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activitatea 2 ===&lt;br /&gt;
&lt;br /&gt;
Modificați implementarea detecției și gestiunii salturilor necondiționate, &amp;#039;&amp;#039;JMP #target&amp;#039;&amp;#039;, astfel încât saltul în program (încărcarea adresei de salt în PC) să aibă loc la sfârșitul etapei READ. În felul acesta se va pierde o singură instrucțiune și nu două.&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Laboratorul_4&amp;diff=8380</id>
		<title>Laboratorul 4</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Laboratorul_4&amp;diff=8380"/>
		<updated>2026-09-29T08:34:34Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Arhitectura Harvard ==&lt;br /&gt;
&lt;br /&gt;
Arhitectura de calculator Harvard are magistrale distincte pentru accesul la program și la date, permițând astfel citirea unei instrucțiuni în paralel cu citirea sau scrierea unei date de către o altă instrucțiune. Programul și datele se află în memorii separate sau într-o memorie comună dar cu porturi multiple de acces.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab4_harvard.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Procesorul pipeline ==&lt;br /&gt;
&lt;br /&gt;
Procesorul are o structură pipeline cu trei niveluri:&lt;br /&gt;
# FETCH - citirea instrucțiunii din memoria de program&lt;br /&gt;
# READ - citirea operanzilor (din registrele sursă)&lt;br /&gt;
# EXECUTE - execuția operației instrucțiunii/accesul în memoria de date&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab4_procesor.png]]&lt;br /&gt;
&lt;br /&gt;
În această lucrare de laborator se va implementa un procesor pipeline fără gestiunea dependențelor de date sau de control, ce procesează setul de instrucțiuni din laboratoarele precedente. Implementarea va reutiliza integral blocurile ALU și REGS proiectate în laboratorul 1, și cu mici modificări memoria din laboratorul 2.&lt;br /&gt;
&lt;br /&gt;
Schema detaliată a structurii pipeline pune în evidență toate căile de date și semnalele de control. Schema este desenată astfel încât fluxul de instrucțiuni și de date să fie de la stânga la dreapta, cu excepția căii de scriere în setul de registre și a semnalului special de control &amp;#039;&amp;#039;&amp;#039;halt&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab4_pipeline.png]]&lt;br /&gt;
&lt;br /&gt;
Modulul procesor va avea o descriere mixtă, structurală, pentru că instanțiază modulele ALU și REGS, și comportamentală, pentru că toate celelalte componente (contor de program, registre pipeline, multiplexoare, logica de generare de semnale de control) sunt descrise folosind construcții &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;assign&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
Pentru a avea un modul verilog ușor de urmărit și de depanat, este de preferat ca ordinea instanțierilor și a diferitelor construcții &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;assign&amp;#039;&amp;#039;&amp;#039; din descriere să corespundă ordonării blocurilor în structura pipeline:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
module processor (&lt;br /&gt;
  // interfața procesorului&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
// declarații semnale interne&lt;br /&gt;
// descrierea PC&lt;br /&gt;
// descrierea R1&lt;br /&gt;
// instanță de modul REGS&lt;br /&gt;
// ș.a.m.d.&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== PC ===&lt;br /&gt;
&lt;br /&gt;
Contorul de program incrementează în fiecare ciclu de ceas cu excepția cazului în care procesorul a fost oprit de instrucțiunea &amp;#039;&amp;#039;HALT&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(rst)&lt;br /&gt;
        pc &amp;lt;= 0;&lt;br /&gt;
    else if(halt)&lt;br /&gt;
        pc &amp;lt;= pc;&lt;br /&gt;
    else &lt;br /&gt;
        pc &amp;lt;= pc + 1;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== FETCH ===&lt;br /&gt;
&lt;br /&gt;
Setul de instrucțiuni fiind foarte simplu pentru acest laborator, nu există logică suplimentară în etapa de citire a instrucțiunii. Procesorul trimite spre memoria de program adresa instrucțiunii, adică valoarea PC, și preia instrucțiunea de la ieșirea acesteia.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign instr_addr = pc;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Registrul pipeline R1 ===&lt;br /&gt;
&lt;br /&gt;
Acesta salvează la finalul ciclului de ceas (de citire a instrucțiunii) instrucțiunea primită de la memoria de program. Actualizarea registrului pipeline este oprită dacă procesorul execută instrucțiunea &amp;#039;&amp;#039;HALT&amp;#039;&amp;#039;. La resetare registrul pipeline este încărcat cu 0, adică cu codul instrucțiunii &amp;#039;&amp;#039;NOP&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(rst)&lt;br /&gt;
        r1 &amp;lt;= 0;&lt;br /&gt;
    else if(halt)&lt;br /&gt;
        r1 &amp;lt;= r1;&lt;br /&gt;
    else&lt;br /&gt;
        r1 &amp;lt;= instr;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== READ ===&lt;br /&gt;
&lt;br /&gt;
În etapa de citire a operanzilor procesorul accesează setul de registre pe baza câmpurilor sursă ale instrucțiunii din registrul R1, preia datele din registrele sursă și livrează operanzii pentru a fi stocați în registrul pipeline următor, R2. Pentru instrucțiunea &amp;#039;&amp;#039;LOADC&amp;#039;&amp;#039; operandul 2 este preluat direct din câmpul constantă al instrucțiunii din R1. Logica de selecție a multiplexorului operandului 2 se bazează pe comparația codului instrucțiunii aflate în această fază de procesare, &amp;#039;&amp;#039;&amp;#039;r1_opcode&amp;#039;&amp;#039;&amp;#039;, cu codul instrucțiunii &amp;#039;&amp;#039;LOADC&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign operand2 = (r1_opcode == 4&amp;#039;b1000) ? r1_instr_data : rdata2; // LOADC are în binar codul 1000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instrucțiunea de atribuire condițională de mai sus este descrierea funcțională a multiplexorului de la intrarea registrului R2 și a blocului logic de generare a semnalului de selecție pentru multiplexor.&lt;br /&gt;
&lt;br /&gt;
Pentru claritatea codului și pentru a identifica ușor semnalele pe formele de undă, folosiți nume dedicate pentru fiecare câmp al instrucțiunii din R1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign r1_opcode     = r1[15:12];&lt;br /&gt;
assign r1_dest       = r1[11: 8];&lt;br /&gt;
assign r1_sursa1     = r1[ 7: 4];&lt;br /&gt;
assign r1_sursa2     =              // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
assign r1_instr_data =              // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Registrul pipeline R2 ===&lt;br /&gt;
&lt;br /&gt;
Acest registru pipeline salvează operanzii și o parte a instrucțiunii ce a trecut de etapa de citire, câmpurile sursă și constantă nemaifiind necesare.&lt;br /&gt;
Spre deosebire de registrul R1 care era declarat ca o singură variabilă &amp;#039;&amp;#039;&amp;#039;r1&amp;#039;&amp;#039;&amp;#039;, registrul R2 este compus din patru variabile distincte.&lt;br /&gt;
Este foarte important ca după execuția instrucțiunii &amp;#039;&amp;#039;HALT&amp;#039;&amp;#039; acest registru pipeline să nu se mai actualizeze - astfel instrucțiunea &amp;#039;&amp;#039;HALT&amp;#039;&amp;#039; rămâne în registrul pipeline R2 asigurând blocarea procesorului până la resetare. La resetare registrul pipeline este încărcat cu 0, adică cu codul instrucțiunii &amp;#039;&amp;#039;NOP&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(rst) begin&lt;br /&gt;
        r2_opcode     &amp;lt;= 0;&lt;br /&gt;
        r2_dest       &amp;lt;= 0;&lt;br /&gt;
        r2_operand1   &amp;lt;= 0;&lt;br /&gt;
        r2_operand2   &amp;lt;= 0;&lt;br /&gt;
    end&lt;br /&gt;
    else if(halt) begin&lt;br /&gt;
        r2_opcode     &amp;lt;=              // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
         . . . . .&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        r2_opcode     &amp;lt;= r1_opcode;&lt;br /&gt;
        r2_dest       &amp;lt;=              // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        r2_operand1   &amp;lt;= operand1;&lt;br /&gt;
        r2_operand2   &amp;lt;=              // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== EXECUTE ===&lt;br /&gt;
&lt;br /&gt;
Logica combinațională de execuție include unitatea aritmetico-logică (ALU). Aceasta preia operanzii salvați în registrul pipeline R2 și livrează rezultatul în baza codului instrucțiunii din același registru. Pentru instrucțiunile de acces la memoria de date (&amp;#039;&amp;#039;LOAD&amp;#039;&amp;#039; și &amp;#039;&amp;#039;STORE&amp;#039;&amp;#039;), operandul 1 este trimis spre aceasta ca adresă de date. Instrucțiunea &amp;#039;&amp;#039;STORE&amp;#039;&amp;#039; trimite și operandul 2, cel ce trebuie salvat în memoria de date, și activează semnalul de control de scriere, &amp;#039;&amp;#039;&amp;#039;write&amp;#039;&amp;#039;&amp;#039;. Instrucțiunea &amp;#039;&amp;#039;LOAD&amp;#039;&amp;#039; preia data citită din memorie, &amp;#039;&amp;#039;&amp;#039;data_in&amp;#039;&amp;#039;&amp;#039;, și o selectează drept rezultat ce trebuie scris în registrul destinație, selecție ce se face comparând codul instrucțiunii din registrul pipeline R2 (codul instrucțiunii aflate în execuție) cu codul instrucțiunii &amp;#039;&amp;#039;LOAD&amp;#039;&amp;#039; (1001 în binar).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign data_addr = r2_operand1;&lt;br /&gt;
assign data_out  =                                                  // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
assign write     =  // activ numai cand STORE e in faza de executie // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
assign result    = (r2_opcode == 4&amp;#039;b1001) ? data_in : alu_result;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tot logica combinațională din etapa de execuție generează și semnalul de control al scrierii în setul de registre. Instrucțiunile &amp;#039;&amp;#039;NOP&amp;#039;&amp;#039; și &amp;#039;&amp;#039;HALT&amp;#039;&amp;#039; nu trebuie să actualizeze nimic, la fel și instrucțiunea &amp;#039;&amp;#039;STORE&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(r2_opcode)&lt;br /&gt;
    4&amp;#039;b0000: regs_wen = 0; // NOP&lt;br /&gt;
    4&amp;#039;b0001: regs_wen = 1; // ADD&lt;br /&gt;
    4&amp;#039;b0010:               // SUB    // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    4&amp;#039;b1000:               // LOADC  // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    4&amp;#039;b1001:               // LOAD   // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    4&amp;#039;b1010:               // STORE  // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    4&amp;#039;b1111:               // HALT   // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    // urmeaza implementarea altor operatii&lt;br /&gt;
    default: regs_wen = 0;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Etapa de execuție trebuie să genereze și semnalul de control &amp;#039;&amp;#039;&amp;#039;halt&amp;#039;&amp;#039;&amp;#039; atunci când instrucțiunea curentă din execuție are codul &amp;#039;&amp;#039;HALT&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign halt =                        // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Memoria de date ==&lt;br /&gt;
&lt;br /&gt;
Este identică cu memoria din laboratorul precedent, dar fără inițializarea programului, acesta fiind stocat în altă memorie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Memoria de program ==&lt;br /&gt;
&lt;br /&gt;
Are nevoie doar de logica de acces pentru citire și blocul de inițializare a programului. Atenție la dimensiunea locațiilor de memorie și a portului de ieșire, instrucțiunea fiind de 16 biți!&lt;br /&gt;
&lt;br /&gt;
=== Initializare program ===&lt;br /&gt;
&lt;br /&gt;
Programul este cel din laboratorul prededent.&lt;br /&gt;
Programul incarcă în primele trei registre trei adrese de memorie, specificate în program ca valori imediate în instrucțiunile LOADC (load constant),&lt;br /&gt;
apoi transferă două numere din ultimele doua locații ale memoriei de date în doua registre, R4 si R5.&lt;br /&gt;
Urmează adunarea celor două numere, rezultatul fiind salvat în registrul R6, rezultat ce apoi este stocat în memoria de date în antepenultima ei locație.&lt;br /&gt;
Ultima instrucțiune oprește definitiv procesorul (din starea halt procesorul nu mai poate fi reactivat decît prin resetare).&lt;br /&gt;
&lt;br /&gt;
Deoarece procesorul implementat nu gestionează dependențele de date este obligatorie introducerea în program a câte unei instrucțiuni &amp;#039;&amp;#039;NOP&amp;#039;&amp;#039; între oricare două instrucțiuni succesive care depind una de alta. Instrucțiunea &amp;#039;&amp;#039;ADD&amp;#039;&amp;#039; din program folosește operandul încărcat în registru de ultima instrucțiune &amp;#039;&amp;#039;LOAD&amp;#039;&amp;#039;, iar instrucțiunea &amp;#039;&amp;#039;STORE&amp;#039;&amp;#039; are ca operand rezultatul instrucțiunii &amp;#039;&amp;#039;ADD&amp;#039;&amp;#039;. Codul instrucțiunii &amp;#039;&amp;#039;NOP&amp;#039;&amp;#039; este 0.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin&lt;br /&gt;
    memory[00] = 16&amp;#039;b1000_0000_1111_1111; // LOADC R0 #255&lt;br /&gt;
    memory[01] = 16&amp;#039;b1000_0001_1111_1110; // LOADC R1 #254&lt;br /&gt;
                                          // LOADC R2 #253         // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
                                          // LOAD  R4 R0           // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
                                          // LOAD  R5 R1           // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
                                          // NOP                   // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
                                          // ADD   R6 R5 R4        // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
                                          // NOP                   // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
                                          // STORE R2 R6           // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
                                          // HALT                  // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modulul de top (calculatorul) ==&lt;br /&gt;
&lt;br /&gt;
Modului de top, a cărui schemă este dată în prima figură, conține trei instanțe, corespunzătoare celor trei blocuri componente ale calculatorului.&lt;br /&gt;
Singurii pini ai modului de top sunt o intrare de ceas și una de reset.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Testarea calculatorului ==&lt;br /&gt;
&lt;br /&gt;
Modulul de testare este identic cu modulul de testare folosit în laboratorul precedent. Practic se schimbă doar numele modulului de top care este verificat, interfața lui rămânând aceeași.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Activități suplimentare ==&lt;br /&gt;
&lt;br /&gt;
=== Activitatea 1 ===&lt;br /&gt;
&lt;br /&gt;
Rearanjați instrucțiunile în memoria de program astfel încât să folosiți o singură instrucțiune &amp;#039;&amp;#039;NOP&amp;#039;&amp;#039; în loc de două. Verificați în simulare că rezultatul execuției programului este cel corect.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activitatea 2 ===&lt;br /&gt;
&lt;br /&gt;
Implementați instrucțiunea de salt necondiționat &amp;#039;&amp;#039;JMP&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
# Alegeți pentru &amp;#039;&amp;#039;opcode&amp;#039;&amp;#039; o combinație neutilizată (de exemplu 1110) și folosiți câmpul constantă (octetul inferior al instrucțiunii) pentru adresa de salt.&lt;br /&gt;
# Modificați logica de selecție a operandului 2 astfel încât constanta să fie selectată atât pentru instrucțiunea &amp;#039;&amp;#039;LOADC&amp;#039;&amp;#039; cât și pentru instrucțiunea &amp;#039;&amp;#039;JMP&amp;#039;&amp;#039;.&lt;br /&gt;
# Modificați logica de generare a semnalelor de control din faza de execuție astfel ca instrucțiunea &amp;#039;&amp;#039;JMP&amp;#039;&amp;#039; să nu activeze scrierea în memorie și nici actualizarea setului de registre.&lt;br /&gt;
# Adăugați logica de generare a semnalului &amp;#039;&amp;#039;&amp;#039;load_pc&amp;#039;&amp;#039;&amp;#039; în faza de execuție a instrucțiunii &amp;#039;&amp;#039;JMP&amp;#039;&amp;#039;.&lt;br /&gt;
# Adăugați în descrierea PC ramura condiționată de activarea semnalului &amp;#039;&amp;#039;&amp;#039;load_pc&amp;#039;&amp;#039;&amp;#039;, în care &amp;#039;&amp;#039;&amp;#039;pc&amp;#039;&amp;#039;&amp;#039; va lua valoarea operandului 2 din registrul pipeline R2.&lt;br /&gt;
&lt;br /&gt;
Verificați corectitudinea implementării instrucțiunii de salt.&lt;br /&gt;
&lt;br /&gt;
# Inserați instrucțiuni de salt în programul folosit în lucrarea de laborator. Pentru că procesorul nu are mecanisme de gestiune a dependențelor de control, orice instrucțiune de salt din program va fi urmată de două instrucțiuni &amp;#039;&amp;#039;NOP&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
  0   LOADC R0 #255&lt;br /&gt;
  1   LOADC R1 #254&lt;br /&gt;
  2   LOADC R2 #253&lt;br /&gt;
  3   LOAD  R4 R0&lt;br /&gt;
  4   LOAD  R5 R1&lt;br /&gt;
  5   JMP   #9&lt;br /&gt;
  6   NOP&lt;br /&gt;
  7   NOP&lt;br /&gt;
  8   HALT&lt;br /&gt;
  9   ADD   R6 R5 R4&lt;br /&gt;
 10   NOP&lt;br /&gt;
 11   STORE R2 R6&lt;br /&gt;
 12   JMP   #8&lt;br /&gt;
 13   NOP&lt;br /&gt;
 14   NOP&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Laboratorul_2&amp;diff=8379</id>
		<title>Laboratorul 2</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Laboratorul_2&amp;diff=8379"/>
		<updated>2026-09-29T08:30:05Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Arhitectura von Neumann ==&lt;br /&gt;
&lt;br /&gt;
Arhitectura de calculator von Neumann este caracterizată printr-o memorie unică, în care se află atât programul cât și datele, și o magistrală unică, folosită pentru transferul instrucțiunilor de la memorie la procesor, a datelor între procesor și memorie sau între procesor și oricare din dispozitivele de intrare/ieșire conectate la magistrală.&lt;br /&gt;
&lt;br /&gt;
În această lucrare de laborator se va realiza un calculator simplu, având doar procesorul și memoria.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab1_neumann.png]]&lt;br /&gt;
&lt;br /&gt;
=== Setul de instrucțiuni ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&lt;br /&gt;
|+ Tabelul 1&lt;br /&gt;
!mnemonică!! opcode!! detalii!!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;NOP&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0000&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; No operation &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ADD&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0001&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- R[sursa1] + R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SUB&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0010&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- R[sursa1] - R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;AND&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0011&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- R[sursa1] &amp;amp; R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OR&amp;lt;/code&amp;gt;  || &amp;lt;code&amp;gt;4&amp;#039;b0100&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- R[sursa1] &amp;amp;#124; R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0101&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- R[sursa1] ^ R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;CMP&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0111&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; Z &amp;lt;- R[sursa1] == R[sursa2], N &amp;lt;- R[sursa1] &amp;gt;= R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LOADC&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b1000&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- instr_data &amp;lt;/code&amp;gt; ||  &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LOAD&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b1001&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- memorie[R[sursa1]] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;STORE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b1010&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; memorie[R[sursa1]] &amp;lt;- R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;HALT&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b1111&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; halt &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Toate instrucțiunile au 16 biți. Cei mai semnificativi 4 biți ai fiecărei instrucțiuni identifică unic instrucțiunea, valoarea acestui câmp fiind codul instrucțiunii (opcode). Ceilalți 12 biți au o semnificație ce depinde de tipul instrucțiunii, conform desenului de mai jos. Instrucțiunile SUB, AND, OR și XOR au același format ca instrucțiunea ADD, CMP are același format cu STORE, iar NOP are formatul identic cu al instrucțiunii HALT.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: instr_format.png]]&lt;br /&gt;
&lt;br /&gt;
== Procesorul ==&lt;br /&gt;
&lt;br /&gt;
Având o singură cale de acces atât pentru instrucțiuni, cât și pentru date, arhitectura von Neumann procesează o instrucțiune în mai mulți pași, în fiecare pas magistrala comună fiind configurată pentru un anumit transfer între blocurile și registrele conectate la aceasta. Secvențierea procesării instrucțiunilor se face cu ajutorul unității de control al procesorului (UCP), aceasta fiind implementată fie ca o mașină de stări, fie ca o structură microprogramabilă.&lt;br /&gt;
&lt;br /&gt;
Schema bloc a procesorului conține o unitate aritmetico-logică cu registre (RALU), un contor de program (PC) ce se poate incrementa sau încărca cu o valoare dată, un registru pentru adresarea memoriei pentru transferul de date (ADDR), registrul instrucțiunii (IR) ce păstrează codul instrucțiunii pe toată durata procesării acesteia și unitatea de control a procesorului (UCP):&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab2_microneumann.png]]&lt;br /&gt;
&lt;br /&gt;
Pentru a nu complica desenul, în schema bloc au fost schițate doar traseele principale (căile de date). Semnalele de control generate de UCP controlează actualizarea tuturor registrelor (incrementarea PC, încărcarea PC, încărcarea ADDR, încărcarea instrucțiunii în IR byte cu byte, scrierea în registrul destinație din RALU precum și activarea scrierii în memoria externă. De asemenea semnalele de control configurează căile de date prin selecțiile corespunzătoare pentru multiplexoarele de acces. Adresa de memorie este fie adresa unui byte de instrucțiune (PC), fie adresa unei locații de date (ADDR). Data de pe magistrala comună este selectată din trei surse posibile, ea putând fi rezultatul RALU, sau data citită din memorie sau o dată imediată din instrucțiune (byte-ul inferior al acesteia).&lt;br /&gt;
&lt;br /&gt;
Pentru a simplifica procesarea internă și pentru a păstra ordinea câmpurilor instrucțiunii (opcode, destinatie, surse) este prevăzut un multiplexor suplimentar care permite selecția  sursei 1 pentru încărcarea adresei folosite de instrucțiunile de transfer cu memoria.&lt;br /&gt;
 &lt;br /&gt;
=== PC ===&lt;br /&gt;
&lt;br /&gt;
Contorul de program este folosit pentru citirea instrucțiunilor din memorie. Acesta poate fi incrementat sau încărcat cu valoarea de pe magistrala de date, dar numai la comanda UCP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(rst)&lt;br /&gt;
        pc &amp;lt;= 0;&lt;br /&gt;
    else begin&lt;br /&gt;
        if(pc_load)&lt;br /&gt;
            pc &amp;lt;= common_data;&lt;br /&gt;
        else if(pc_incr)&lt;br /&gt;
            // incrementare    // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        else&lt;br /&gt;
            pc &amp;lt;= pc;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ADDR ===&lt;br /&gt;
&lt;br /&gt;
Registrul de adresare a memoriei pentru citirea datelor este un registru elementar ce poate fi doar încărcat:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(rst)&lt;br /&gt;
        data_addr &amp;lt;= 0;&lt;br /&gt;
    else begin&lt;br /&gt;
        if(addr_load)&lt;br /&gt;
            data_addr &amp;lt;= common_data;&lt;br /&gt;
        else&lt;br /&gt;
            data_addr &amp;lt;= data_addr;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IR ===&lt;br /&gt;
&lt;br /&gt;
Instrucțiunea fiind pe 16 biți este nevoie de două accese succesive la memorie, la adrese consecutive, pentru a încărca fiecare byte al registrului instrucțiunii.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(rst)&lt;br /&gt;
        instruction &amp;lt;= 0;&lt;br /&gt;
    else begin&lt;br /&gt;
        if(ir_load_high)&lt;br /&gt;
            instruction[15:8] &amp;lt;= common_data;&lt;br /&gt;
        else if(ir_load_low)&lt;br /&gt;
            // încărcarea byte-ului inferior al instrucțiunii                // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        else&lt;br /&gt;
            instruction &amp;lt;= instruction;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Decodarea instrucțiunii este elementară și constă în separarea câmpurilor instrucțiunii:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign opcode     = instruction[15:12];&lt;br /&gt;
assign dest       = // dest este următorul câmp de 4 biți al instrucțiunii;  // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
assign sursa1     = instruction[ 7: 4];&lt;br /&gt;
assign sursa2     = addr_load ? instruction[ 7: 4] : instruction[ 3: 0];&lt;br /&gt;
// instr_data este byte-ul inferior al instrucțiunii                         // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Byte-ul superior este la prima adresa și conține opcode-ul și câmpul destinație.&lt;br /&gt;
&lt;br /&gt;
=== Multiplexorul căii comune de date ===&lt;br /&gt;
&lt;br /&gt;
Selectează sursa pentru data ce tranzitează calea comună de date.&lt;br /&gt;
Aceasta poate fi byte-ul inferior al IR (pentru transferul unei constante din corpul instrucțiunii), intrarea de date dinspre memorie (pentru citirea instrucțiunii sau pentru citirea unei date din memorie) sau ieșirea RALU (pentru salvarea rezultatului ALU).&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;sel_mem_data&amp;#039;&amp;#039;&amp;#039; selectează intrarea de date dinspre memorie, iar &amp;#039;&amp;#039;&amp;#039;sel_instr_data&amp;#039;&amp;#039;&amp;#039; selectează constanta. Dacă niciunul din cele două semnale de selecție nu este activ se selectează (implicit) rezultatul ALU:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    if(sel_mem_data)&lt;br /&gt;
        common_data = data_in; // se selectează data dinspre memorie&lt;br /&gt;
    else if(sel_instr_data)&lt;br /&gt;
        common_data =          // se selectează constanta             // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    else&lt;br /&gt;
                               // se selectează rezultatul de la ALU  // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UCP ==&lt;br /&gt;
&lt;br /&gt;
Unitatea de control a procesorului controlează actualizarea fiecărui registru din procesor, accesul la magistrala comună de date și multiplexarea adreselor spre memorie.&lt;br /&gt;
Ea se implementează ca un FSM cu câteva stări și tranziții ce depind de tipul instrucțiunii. Ieșirile UCP sunt semnalele de control generate de FSM.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab1_fsmneumann.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== stările ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam FETCH1  = 3&amp;#039;d0;&lt;br /&gt;
localparam FETCH2  = 3&amp;#039;d1;&lt;br /&gt;
localparam EXECUTE = 3&amp;#039;d2;&lt;br /&gt;
localparam LDADDR  = 3&amp;#039;d3;&lt;br /&gt;
localparam LDCONST = 3&amp;#039;d4;&lt;br /&gt;
localparam LD_DATA = 3&amp;#039;d5;&lt;br /&gt;
localparam ST_DATA = 3&amp;#039;d6;&lt;br /&gt;
localparam HALT    = 3&amp;#039;d7;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== tranzițiile ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(rst) begin&lt;br /&gt;
        state &amp;lt;= FETCH1;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
&lt;br /&gt;
        FETCH1: state &amp;lt;= FETCH2;&lt;br /&gt;
		  &lt;br /&gt;
        FETCH2: begin&lt;br /&gt;
            case(opcode)&lt;br /&gt;
                4&amp;#039;b0000: state &amp;lt;= FETCH1;  // NOP&lt;br /&gt;
                4&amp;#039;b0001: state &amp;lt;= EXECUTE; // ADD&lt;br /&gt;
                4&amp;#039;b1000: state &amp;lt;= LDCONST; // LOADC&lt;br /&gt;
                4&amp;#039;b1001:                   // LOAD     // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
                4&amp;#039;b1010:                   // STORE    // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
                4&amp;#039;b1111:                   // HALT     // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
           endcase&lt;br /&gt;
        end&lt;br /&gt;
		  &lt;br /&gt;
        LDCONST: state &amp;lt;= FETCH1;&lt;br /&gt;
		  &lt;br /&gt;
        LDADDR:  begin&lt;br /&gt;
            if(opcode == 4&amp;#039;b1001)&lt;br /&gt;
                state &amp;lt;= LD_DATA;&lt;br /&gt;
            if(opcode == 4&amp;#039;b1010)&lt;br /&gt;
                state &amp;lt;= ST_DATA;&lt;br /&gt;
        end&lt;br /&gt;
		  &lt;br /&gt;
        LD_DATA: state &amp;lt;= FETCH1;	  &lt;br /&gt;
        ST_DATA:                           // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        EXECUTE:                           // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        HALT:                              // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        default: state &amp;lt;= HALT;&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== semnalele de control ===&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie compact codul generării tuturor semnalelor de control, acestea sunt grupate într-un vector de 10 biți, &amp;#039;&amp;#039;&amp;#039;control_vector&amp;#039;&amp;#039;&amp;#039;,&lt;br /&gt;
fiecare semnal de control fiind un anumit bit al acestuia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
logic [9:0] control_vector;&lt;br /&gt;
&lt;br /&gt;
assign pc_incr        = control_vector[9];&lt;br /&gt;
assign pc_load        = control_vector[8];&lt;br /&gt;
assign addr_load      = control_vector[7];&lt;br /&gt;
assign sel_addr       = control_vector[6];&lt;br /&gt;
assign sel_mem_data   = control_vector[5];&lt;br /&gt;
assign sel_instr_data = control_vector[4];&lt;br /&gt;
assign ir_load_high   = control_vector[3];&lt;br /&gt;
assign ir_load_low    = control_vector[2];&lt;br /&gt;
assign regs_wen       = control_vector[1];&lt;br /&gt;
assign write          = control_vector[0];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Valorile biților de control sunt generate în fiecare stare corespunzător resurselor pe care procesorul le folosește sau le controlează în acea stare:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(state)&lt;br /&gt;
        FETCH1:  control_vector = 10&amp;#039;b10_0010_1000; // PC &amp;lt;- PC + 1, IRH &amp;lt;- data_from_mem &lt;br /&gt;
        FETCH2:                                     // PC &amp;lt;- PC + 1, IRL &amp;lt;- data_from_mem       // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        LDCONST: control_vector = 10&amp;#039;b00_0001_0010; // R[dest] &amp;lt;- instrdata &lt;br /&gt;
        LDADDR:  control_vector = 10&amp;#039;b00_1000_0000; // ADDR &amp;lt;- result, &lt;br /&gt;
        EXECUTE:                                    // R[dest] &amp;lt;- result                        // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        LD_DATA: control_vector = 10&amp;#039;b00_0110_0010; // addr = ADDR, R[dest] &amp;lt;- data_from_mem&lt;br /&gt;
        ST_DATA: control_vector = 10&amp;#039;b00_0100_0001; // addr = ADDR, write&lt;br /&gt;
        HALT:    control_vector = 10&amp;#039;b00_0000_0000; // nothing to do&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Memoria ==&lt;br /&gt;
&lt;br /&gt;
Pentru lucrarea 2 se va considera o memorie simplă, de 2 kb, cu 256 locații de 8 biți fiecare, cu un singur port de date, cu intrare și ieșire separate.&lt;br /&gt;
Citirea are loc instantaneu, iar scrierea se execută sincron, la finalul ciclului de ceas de acces, dacă semnalul de scriere este activ. Memoria nu folosește semnalul de reset.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
logic [7:0] memory [0:255];&lt;br /&gt;
// citire din memorie&lt;br /&gt;
assign dout = memory[addr];&lt;br /&gt;
// scriere in memorie&lt;br /&gt;
always_ff @(posedge clk)&lt;br /&gt;
    if(write) memory[addr] &amp;lt;= din;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Inițializarea memoriei ===&lt;br /&gt;
&lt;br /&gt;
Memoria calculatorului, fiind unică, conține atât programul cât și datele.&lt;br /&gt;
Organizarea ei este la latitudinea programatorului, dar trebuie ținut cont de faptul că la resetare contorul de program (PC) ia valoarea 0.&lt;br /&gt;
Prima instrucțiune citită de procesor va fi cea de la locațiile cu adresele 0 și 1.&lt;br /&gt;
&lt;br /&gt;
Pentru lucrarea de laborator se va inițializa memoria cu o secvență de instrucțiuni în locații succesive începînd cu adresa 0 (programul)&lt;br /&gt;
și cu câteva valori numerice întregi, de 8 biți, la ultimele adrese din memorie (datele programului).&lt;br /&gt;
Locațiile inițializate ca date trebuie să coincidă cu locațiile adresate prin program pentru a putea procesa acele date.&lt;br /&gt;
&lt;br /&gt;
=== Initializare program ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin&lt;br /&gt;
    {memory[00], memory[01]} = 16&amp;#039;b1000_0000_1111_1111; // LOADC R0 #255&lt;br /&gt;
    {memory[02], memory[03]} = 16&amp;#039;b1000_0001_1111_1110; // LOADC R1 #254&lt;br /&gt;
                                                        // LOADC R2 #253         // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    {memory[06], memory[07]} = 16&amp;#039;b1001_0100_0000_0000; // LOAD  R4 R0&lt;br /&gt;
                                                        // LOAD  R5 R1           // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    {memory[10], memory[11]} = 16&amp;#039;b0001_0110_0101_0100; // ADD   R6 R5 R4&lt;br /&gt;
    {memory[12], memory[13]} = 16&amp;#039;b1010_0000_0010_0110; // STORE R2 R6&lt;br /&gt;
    {memory[14], memory[15]} = 16&amp;#039;b1111_1111_1111_1111; // HALT&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Programul de mai sus incarcă în primele trei registre trei adrese de memorie, date în program ca valori imediate în instrucțiunile LOADC (load constant),&lt;br /&gt;
apoi transferă două numere din ultimele doua locații de memorie în doua registre, R4 si R5.&lt;br /&gt;
Urmează adunarea celor două numere, rezultatul fiind salvat în registrul R6, rezultat ce apoi este stocat în memorie în antepenultima ei locație.&lt;br /&gt;
Ultima instrucțiune oprește definitiv procesorul (din starea halt procesorul nu mai poate fi reactivat decît prin resetare)&lt;br /&gt;
&lt;br /&gt;
=== Initializare date ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin&lt;br /&gt;
    memory[254] = 17;&lt;br /&gt;
    memory[255] = 23;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modulul de top (calculatorul) ==&lt;br /&gt;
&lt;br /&gt;
Fiind un calculator simplu, format doar din procesor și memorie, modulul de top (&amp;#039;&amp;#039;&amp;#039;neumann&amp;#039;&amp;#039;&amp;#039;) conține doar două instanțe, corespunzătoare celor două blocuri componente ale calculatorului.&lt;br /&gt;
Singurii pini ai modului de top sunt o intrare de ceas și una de reset.&lt;br /&gt;
Nu uitați să declarați conexiunile interne dintre cele două instanțe, conexiuni multibit, &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;data_to_mem&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;data_from_mem&amp;#039;&amp;#039;&amp;#039;,&lt;br /&gt;
și să conectați semnalul de control al scrierii în memorie.&lt;br /&gt;
&lt;br /&gt;
== Testarea calculatorului ==&lt;br /&gt;
&lt;br /&gt;
Scrieți modulul de testare, în care instanțiați calculatorul descris mai sus și generați cele două semnale de intrare, &amp;#039;&amp;#039;&amp;#039;clk&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
module neumann_tb;&lt;br /&gt;
&lt;br /&gt;
// declarații de variable&lt;br /&gt;
&lt;br /&gt;
// instanțierea calculatorului	 &lt;br /&gt;
&lt;br /&gt;
// generarea semnalului de ceas&lt;br /&gt;
&lt;br /&gt;
// generarea semnalului de reset&lt;br /&gt;
&lt;br /&gt;
// un bloc initial pentru oprirea simularii&lt;br /&gt;
initial begin&lt;br /&gt;
    repeat (100) @(posedge clk);&lt;br /&gt;
    $stop;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Activități suplimentare ==&lt;br /&gt;
&lt;br /&gt;
=== Activitatea 1 ===&lt;br /&gt;
&lt;br /&gt;
Pentru procesarea instrucțiunilor NOP și HALT este suficient codul instrucțiunii. Setul de instrucțiuni optimizat folosește doar 8 biți pentru instrucțiunile NOP și HALT, primii 4 biți reprezentând codul instrucțiunii. Modificați calculatorul astfel încât acesta să poată procesa setul de instrucțiuni astfel optimizat:&lt;br /&gt;
* Unitatea de Control a procesorului are nevoie doar de starea FETCH1 pentru citirea instrucțiunilor NOP și HALT. După starea FETCH1 UCP trece în starea HALT pentru instrucțiunea omonimă, în aceeași stare FETCH1 pentru instrucțiunea NOP, respectiv în starea FETCH2 pentru orice altă instrucțiune.&lt;br /&gt;
* În memoria de program instrucțiunile NOP și HALT ocupă câte o singură locație de memorie (un octet), spre deosebire de celelalte instrucțiuni, ce ocupă două locații (doi octeți). Inserați în programul din memorie două instrucțiuni NOP, rezultând următoarea secvență de instrucțiuni:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
    LOADC R0 #255&lt;br /&gt;
    LOADC R1 #254&lt;br /&gt;
    LOADC R2 #253&lt;br /&gt;
    LOAD  R4 R0&lt;br /&gt;
    LOAD  R5 R1&lt;br /&gt;
    NOP&lt;br /&gt;
    ADD   R6 R5 R4&lt;br /&gt;
    NOP&lt;br /&gt;
    STORE R2 R6&lt;br /&gt;
    HALT&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atenție la locațiile de memorie ale instrucțiunilor!&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Laboratorul_2&amp;diff=8378</id>
		<title>Laboratorul 2</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Laboratorul_2&amp;diff=8378"/>
		<updated>2026-09-29T08:24:24Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* PC */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Arhitectura von Neumann ==&lt;br /&gt;
&lt;br /&gt;
Arhitectura de calculator von Neumann este caracterizată printr-o memorie unică, în care se află atât programul cât și datele, și o magistrală unică, folosită pentru transferul instrucțiunilor de la memorie la procesor, a datelor între procesor și memorie sau între procesor și oricare din dispozitivele de intrare/ieșire conectate la magistrală.&lt;br /&gt;
&lt;br /&gt;
În această lucrare de laborator se va realiza un calculator simplu, având doar procesorul și memoria.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab1_neumann.png]]&lt;br /&gt;
&lt;br /&gt;
=== Setul de instrucțiuni ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&lt;br /&gt;
|+ Tabelul 1&lt;br /&gt;
!mnemonică!! opcode!! detalii!!&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;NOP&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0000&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; No operation &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ADD&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0001&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- R[sursa1] + R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SUB&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0010&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- R[sursa1] - R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;AND&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0011&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- R[sursa1] &amp;amp; R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OR&amp;lt;/code&amp;gt;  || &amp;lt;code&amp;gt;4&amp;#039;b0100&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- R[sursa1] &amp;amp;#124; R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0101&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- R[sursa1] ^ R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;CMP&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b0111&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; Z &amp;lt;- R[sursa1] == R[sursa2], N &amp;lt;- R[sursa1] &amp;gt;= R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LOADC&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b1000&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- instr_data &amp;lt;/code&amp;gt; ||  &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LOAD&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b1001&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; R[dest] &amp;lt;- memorie[R[sursa1]] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;STORE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b1010&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; memorie[R[sursa1]] &amp;lt;- R[sursa2] &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;HALT&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;4&amp;#039;b1111&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt; halt &amp;lt;/code&amp;gt; ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Toate instrucțiunile au 16 biți. Cei mai semnificativi 4 biți ai fiecărei instrucțiuni identifică unic instrucțiunea, valoarea acestui câmp fiind codul instrucțiunii (opcode). Ceilalți 12 biți au o semnificație ce depinde de tipul instrucțiunii, conform desenului de mai jos. Instrucțiunile SUB, AND, OR și XOR au același format ca instrucțiunea ADD, CMP are același format cu STORE, iar NOP are formatul identic cu al instrucțiunii HALT.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: instr_format.png]]&lt;br /&gt;
&lt;br /&gt;
== Procesorul ==&lt;br /&gt;
&lt;br /&gt;
Având o singură cale de acces atât pentru instrucțiuni, cât și pentru date, arhitectura von Neumann procesează o instrucțiune în mai mulți pași, în fiecare pas magistrala comună fiind configurată pentru un anumit transfer între blocurile și registrele conectate la aceasta. Secvențierea procesării instrucțiunilor se face cu ajutorul unității de control al procesorului (UCP), aceasta fiind implementată fie ca o mașină de stări, fie ca o structură microprogramabilă.&lt;br /&gt;
&lt;br /&gt;
Schema bloc a procesorului conține o unitate aritmetico-logică cu registre (RALU), un contor de program (PC) ce se poate incrementa sau încărca cu o valoare dată, un registru pentru adresarea memoriei pentru transferul de date (ADDR), registrul instrucțiunii (IR) ce păstrează codul instrucțiunii pe toată durata procesării acesteia și unitatea de control a procesorului (UCP):&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab2_microneumann.png]]&lt;br /&gt;
&lt;br /&gt;
Pentru a nu complica desenul, în schema bloc au fost schițate doar traseele principale (căile de date). Semnalele de control generate de UCP controlează actualizarea tuturor registrelor (incrementarea PC, încărcarea PC, încărcarea ADDR, încărcarea instrucțiunii în IR byte cu byte, scrierea în registrul destinație din RALU precum și activarea scrierii în memoria externă. De asemenea semnalele de control configurează căile de date prin selecțiile corespunzătoare pentru multiplexoarele de acces. Adresa de memorie este fie adresa unui byte de instrucțiune (PC), fie adresa unei locații de date (ADDR). Data de pe magistrala comună este selectată din trei surse posibile, ea putând fi rezultatul RALU, sau data citită din memorie sau o dată imediată din instrucțiune (byte-ul inferior al acesteia).&lt;br /&gt;
&lt;br /&gt;
Pentru a simplifica procesarea internă și pentru a păstra ordinea câmpurilor instrucțiunii (opcode, destinatie, surse) este prevăzut un multiplexor suplimentar care permite selecția  sursei 1 pentru încărcarea adresei folosite de instrucțiunile de transfer cu memoria.&lt;br /&gt;
 &lt;br /&gt;
=== PC ===&lt;br /&gt;
&lt;br /&gt;
Contorul de program este folosit pentru citirea instrucțiunilor din memorie. Acesta poate fi incrementat sau încărcat cu valoarea de pe magistrala de date, dar numai la comanda UCP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(rst)&lt;br /&gt;
        pc &amp;lt;= 0;&lt;br /&gt;
    else begin&lt;br /&gt;
        if(pc_load)&lt;br /&gt;
            pc &amp;lt;= common_data;&lt;br /&gt;
        else if(pc_incr)&lt;br /&gt;
            // incrementare    // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        else&lt;br /&gt;
            pc &amp;lt;= pc;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ADDR ===&lt;br /&gt;
&lt;br /&gt;
Registrul de adresare a memoriei pentru citirea datelor este un registru elementar ce poate fi doar încărcat:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(rst)&lt;br /&gt;
        data_addr &amp;lt;= 0;&lt;br /&gt;
    else begin&lt;br /&gt;
        if(addr_load)&lt;br /&gt;
            data_addr &amp;lt;= common_data;&lt;br /&gt;
        else&lt;br /&gt;
            data_addr &amp;lt;= data_addr;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IR ===&lt;br /&gt;
&lt;br /&gt;
Instrucțiunea fiind pe 16 biți este nevoie de două accese succesive la memorie, la adrese consecutive, pentru a încărca fiecare byte al registrului instrucțiunii.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(rst)&lt;br /&gt;
        instruction &amp;lt;= 0;&lt;br /&gt;
    else begin&lt;br /&gt;
        if(ir_load_high)&lt;br /&gt;
            instruction[15:8] &amp;lt;= common_data;&lt;br /&gt;
        else if(ir_load_low)&lt;br /&gt;
            // încărcarea byte-ului inferior al instrucțiunii                // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        else&lt;br /&gt;
            instruction &amp;lt;= instruction;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Decodarea instrucțiunii este elementară și constă în separarea câmpurilor instrucțiunii:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign opcode     = instruction[15:12];&lt;br /&gt;
assign dest       = // dest este următorul câmp de 4 biți al instrucțiunii;  // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
assign sursa1     = instruction[ 7: 4];&lt;br /&gt;
assign sursa2     = addr_load ? instruction[ 7: 4] : instruction[ 3: 0];&lt;br /&gt;
// instr_data este byte-ul inferior al instrucțiunii                         // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Byte-ul superior este la prima adresa și conține opcode-ul și câmpul destinație.&lt;br /&gt;
&lt;br /&gt;
=== Multiplexorul căii comune de date ===&lt;br /&gt;
&lt;br /&gt;
Selectează sursa pentru data ce tranzitează calea comună de date.&lt;br /&gt;
Aceasta poate fi byte-ul inferior al IR (pentru transferul unei constante din corpul instrucțiunii), intrarea de date dinspre memorie (pentru citirea instrucțiunii sau pentru citirea unei date din memorie) sau ieșirea RALU (pentru salvarea rezultatului ALU).&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;sel_mem_data&amp;#039;&amp;#039;&amp;#039; selectează intrarea de date dinspre memorie, iar &amp;#039;&amp;#039;&amp;#039;sel_instr_data&amp;#039;&amp;#039;&amp;#039; selectează constanta. Dacă niciunul din cele două semnale de selecție nu este activ se selectează (implicit) rezultatul ALU:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(*) begin&lt;br /&gt;
    if(sel_mem_data)&lt;br /&gt;
        common_data = data_in; // se selectează data dinspre memorie&lt;br /&gt;
    else if(sel_instr_data)&lt;br /&gt;
        common_data =          // se selectează constanta             // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    else&lt;br /&gt;
                               // se selectează rezultatul de la ALU  // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== UCP ==&lt;br /&gt;
&lt;br /&gt;
Unitatea de control a procesorului controlează actualizarea fiecărui registru din procesor, accesul la magistrala comună de date și multiplexarea adreselor spre memorie.&lt;br /&gt;
Ea se implementează ca un FSM cu câteva stări și tranziții ce depind de tipul instrucțiunii. Ieșirile UCP sunt semnalele de control generate de FSM.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab1_fsmneumann.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== stările ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam FETCH1  = 3&amp;#039;d0;&lt;br /&gt;
localparam FETCH2  = 3&amp;#039;d1;&lt;br /&gt;
localparam EXECUTE = 3&amp;#039;d2;&lt;br /&gt;
localparam LDADDR  = 3&amp;#039;d3;&lt;br /&gt;
localparam LDCONST = 3&amp;#039;d4;&lt;br /&gt;
localparam LD_DATA = 3&amp;#039;d5;&lt;br /&gt;
localparam ST_DATA = 3&amp;#039;d6;&lt;br /&gt;
localparam HALT    = 3&amp;#039;d7;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== tranzițiile ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(rst) begin&lt;br /&gt;
        state &amp;lt;= FETCH1;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
&lt;br /&gt;
        FETCH1: state &amp;lt;= FETCH2;&lt;br /&gt;
		  &lt;br /&gt;
        FETCH2: begin&lt;br /&gt;
            case(opcode)&lt;br /&gt;
                4&amp;#039;b0000: state &amp;lt;= FETCH1;  // NOP&lt;br /&gt;
                4&amp;#039;b0001: state &amp;lt;= EXECUTE; // ADD&lt;br /&gt;
                4&amp;#039;b1000: state &amp;lt;= LDCONST; // LOADC&lt;br /&gt;
                4&amp;#039;b1001:                   // LOAD     // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
                4&amp;#039;b1010:                   // STORE    // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
                4&amp;#039;b1111:                   // HALT     // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
           endcase&lt;br /&gt;
        end&lt;br /&gt;
		  &lt;br /&gt;
        LDCONST: state &amp;lt;= FETCH1;&lt;br /&gt;
		  &lt;br /&gt;
        LDADDR:  begin&lt;br /&gt;
            if(opcode == 4&amp;#039;b1001)&lt;br /&gt;
                state &amp;lt;= LD_DATA;&lt;br /&gt;
            if(opcode == 4&amp;#039;b1010)&lt;br /&gt;
                state &amp;lt;= ST_DATA;&lt;br /&gt;
        end&lt;br /&gt;
		  &lt;br /&gt;
        LD_DATA: state &amp;lt;= FETCH1;	  &lt;br /&gt;
        ST_DATA:                           // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        EXECUTE:                           // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        HALT:                              // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        default: state &amp;lt;= HALT;&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== semnalele de control ===&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie compact codul generării tuturor semnalelor de control, acestea sunt grupate într-un vector de 10 biți, &amp;#039;&amp;#039;&amp;#039;control_vector&amp;#039;&amp;#039;&amp;#039;,&lt;br /&gt;
fiecare semnal de control fiind un anumit bit al acestuia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
reg [9:0] control_vector;&lt;br /&gt;
&lt;br /&gt;
assign pc_incr        = control_vector[9];&lt;br /&gt;
assign pc_load        = control_vector[8];&lt;br /&gt;
assign addr_load      = control_vector[7];&lt;br /&gt;
assign sel_addr       = control_vector[6];&lt;br /&gt;
assign sel_mem_data   = control_vector[5];&lt;br /&gt;
assign sel_instr_data = control_vector[4];&lt;br /&gt;
assign ir_load_high   = control_vector[3];&lt;br /&gt;
assign ir_load_low    = control_vector[2];&lt;br /&gt;
assign regs_wen       = control_vector[1];&lt;br /&gt;
assign write          = control_vector[0];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Valorile biților de control sunt generate în fiecare stare corespunzător resurselor pe care procesorul le folosește sau le controlează în acea stare:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(*) begin&lt;br /&gt;
    case(state)&lt;br /&gt;
        FETCH1:  control_vector = 10&amp;#039;b10_0010_1000; // PC &amp;lt;- PC + 1, IRH &amp;lt;- data_from_mem &lt;br /&gt;
        FETCH2:                                     // PC &amp;lt;- PC + 1, IRL &amp;lt;- data_from_mem       // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        LDCONST: control_vector = 10&amp;#039;b00_0001_0010; // R[dest] &amp;lt;- instrdata &lt;br /&gt;
        LDADDR:  control_vector = 10&amp;#039;b00_1000_0000; // ADDR &amp;lt;- result, &lt;br /&gt;
        EXECUTE:                                    // R[dest] &amp;lt;- result                        // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
        LD_DATA: control_vector = 10&amp;#039;b00_0110_0010; // addr = ADDR, R[dest] &amp;lt;- data_from_mem&lt;br /&gt;
        ST_DATA: control_vector = 10&amp;#039;b00_0100_0001; // addr = ADDR, write&lt;br /&gt;
        HALT:    control_vector = 10&amp;#039;b00_0000_0000; // nothing to do&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Memoria ==&lt;br /&gt;
&lt;br /&gt;
Pentru lucrarea 2 se va considera o memorie simplă, de 2 kb, cu 256 locații de 8 biți fiecare, cu un singur port de date, cu intrare și ieșire separate.&lt;br /&gt;
Citirea are loc instantaneu, iar scrierea se execută sincron, la finalul ciclului de ceas de acces, dacă semnalul de scriere este activ. Memoria nu folosește semnalul de reset.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
reg [7:0] memory [0:255];&lt;br /&gt;
// citire din memorie&lt;br /&gt;
assign dout = memory[addr];&lt;br /&gt;
// scriere in memorie&lt;br /&gt;
always @(posedge clk) if(write) memory[addr] &amp;lt;= din;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Inițializarea memoriei ===&lt;br /&gt;
&lt;br /&gt;
Memoria calculatorului, fiind unică, conține atât programul cât și datele.&lt;br /&gt;
Organizarea ei este la latitudinea programatorului, dar trebuie ținut cont de faptul că la resetare contorul de program (PC) ia valoarea 0.&lt;br /&gt;
Prima instrucțiune citită de procesor va fi cea de la locațiile cu adresele 0 și 1.&lt;br /&gt;
&lt;br /&gt;
Pentru lucrarea de laborator se va inițializa memoria cu o secvență de instrucțiuni în locații succesive începînd cu adresa 0 (programul)&lt;br /&gt;
și cu câteva valori numerice întregi, de 8 biți, la ultimele adrese din memorie (datele programului).&lt;br /&gt;
Locațiile inițializate ca date trebuie să coincidă cu locațiile adresate prin program pentru a putea procesa acele date.&lt;br /&gt;
&lt;br /&gt;
=== Initializare program ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin&lt;br /&gt;
    {memory[00], memory[01]} = 16&amp;#039;b1000_0000_1111_1111; // LOADC R0 #255&lt;br /&gt;
    {memory[02], memory[03]} = 16&amp;#039;b1000_0001_1111_1110; // LOADC R1 #254&lt;br /&gt;
                                                        // LOADC R2 #253         // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    {memory[06], memory[07]} = 16&amp;#039;b1001_0100_0000_0000; // LOAD  R4 R0&lt;br /&gt;
                                                        // LOAD  R5 R1           // &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; COMPLETAȚI CODUL !&lt;br /&gt;
    {memory[10], memory[11]} = 16&amp;#039;b0001_0110_0101_0100; // ADD   R6 R5 R4&lt;br /&gt;
    {memory[12], memory[13]} = 16&amp;#039;b1010_0000_0010_0110; // STORE R2 R6&lt;br /&gt;
    {memory[14], memory[15]} = 16&amp;#039;b1111_1111_1111_1111; // HALT&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Programul de mai sus incarcă în primele trei registre trei adrese de memorie, date în program ca valori imediate în instrucțiunile LOADC (load constant),&lt;br /&gt;
apoi transferă două numere din ultimele doua locații de memorie în doua registre, R4 si R5.&lt;br /&gt;
Urmează adunarea celor două numere, rezultatul fiind salvat în registrul R6, rezultat ce apoi este stocat în memorie în antepenultima ei locație.&lt;br /&gt;
Ultima instrucțiune oprește definitiv procesorul (din starea halt procesorul nu mai poate fi reactivat decît prin resetare)&lt;br /&gt;
&lt;br /&gt;
=== Initializare date ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin&lt;br /&gt;
    memory[254] = 17;&lt;br /&gt;
    memory[255] = 23;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modulul de top (calculatorul) ==&lt;br /&gt;
&lt;br /&gt;
Fiind un calculator simplu, format doar din procesor și memorie, modulul de top (&amp;#039;&amp;#039;&amp;#039;neumann&amp;#039;&amp;#039;&amp;#039;) conține doar două instanțe, corespunzătoare celor două blocuri componente ale calculatorului.&lt;br /&gt;
Singurii pini ai modului de top sunt o intrare de ceas și una de reset.&lt;br /&gt;
Nu uitați să declarați conexiunile interne dintre cele două instanțe, conexiuni multibit, &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;data_to_mem&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;data_from_mem&amp;#039;&amp;#039;&amp;#039;,&lt;br /&gt;
și să conectați semnalul de control al scrierii în memorie.&lt;br /&gt;
&lt;br /&gt;
== Testarea calculatorului ==&lt;br /&gt;
&lt;br /&gt;
Scrieți modulul de testare, în care instanțiați calculatorul descris mai sus și generați cele două semnale de intrare, &amp;#039;&amp;#039;&amp;#039;clk&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module neumann_tb;&lt;br /&gt;
&lt;br /&gt;
// declarații de variable&lt;br /&gt;
&lt;br /&gt;
// instanțierea calculatorului	 &lt;br /&gt;
&lt;br /&gt;
// generarea semnalului de ceas&lt;br /&gt;
&lt;br /&gt;
// generarea semnalului de reset&lt;br /&gt;
&lt;br /&gt;
// un bloc initial pentru oprirea simularii&lt;br /&gt;
initial begin&lt;br /&gt;
    repeat (100) @(posedge clk);&lt;br /&gt;
    $stop;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Activități suplimentare ==&lt;br /&gt;
&lt;br /&gt;
=== Activitatea 1 ===&lt;br /&gt;
&lt;br /&gt;
Pentru procesarea instrucțiunilor NOP și HALT este suficient codul instrucțiunii. Setul de instrucțiuni optimizat folosește doar 8 biți pentru instrucțiunile NOP și HALT, primii 4 biți reprezentând codul instrucțiunii. Modificați calculatorul astfel încât acesta să poată procesa setul de instrucțiuni astfel optimizat:&lt;br /&gt;
* Unitatea de Control a procesorului are nevoie doar de starea FETCH1 pentru citirea instrucțiunilor NOP și HALT. După starea FETCH1 UCP trece în starea HALT pentru instrucțiunea omonimă, în aceeași stare FETCH1 pentru instrucțiunea NOP, respectiv în starea FETCH2 pentru orice altă instrucțiune.&lt;br /&gt;
* În memoria de program instrucțiunile NOP și HALT ocupă câte o singură locație de memorie (un octet), spre deosebire de celelalte instrucțiuni, ce ocupă două locații (doi octeți). Inserați în programul din memorie două instrucțiuni NOP, rezultând următoarea secvență de instrucțiuni:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
    LOADC R0 #255&lt;br /&gt;
    LOADC R1 #254&lt;br /&gt;
    LOADC R2 #253&lt;br /&gt;
    LOAD  R4 R0&lt;br /&gt;
    LOAD  R5 R1&lt;br /&gt;
    NOP&lt;br /&gt;
    ADD   R6 R5 R4&lt;br /&gt;
    NOP&lt;br /&gt;
    STORE R2 R6&lt;br /&gt;
    HALT&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Atenție la locațiile de memorie ale instrucțiunilor!&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Laboratorul_1&amp;diff=8377</id>
		<title>Laboratorul 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Laboratorul_1&amp;diff=8377"/>
		<updated>2026-09-29T08:20:01Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== ALU ===&lt;br /&gt;
Unitatea aritmetico-logică, ALU, este responsabilă de execuţia instrucţiunilor.&lt;br /&gt;
În primul rând, după cum ne şi sugerează numele, instrucţiunile aritmetice şi cele logice, dar şi celelalte categorii de instrucţiuni, în execuţia cărora intervin operaţii precum calculul unor adrese pentru instrucţiunile de acces la memorie sau pentru instrucţiunile de salt relativ.&lt;br /&gt;
Concret, ALU primeşte operanzii unei instrucţiuni şi oferă rezultatul operaţiei specificate în codul instrucţiunii. De exemplu instrucţiunea de adunare determină în ALU adunarea celor doi operanzi de la intrare, suma acestora (rezultatul) apărând la ieşirea ALU. Un alt exemplu, instrucţiunea de salt relativ determină în ALU adunarea a două numere, valoarea contorului de program (PC) şi valoarea saltului relativ specificată în corpul instrucţiunii, rezultatul fiind noua valoare de contor de program, ce va fi încărcată în contorul de program.&lt;br /&gt;
&lt;br /&gt;
Complexitatea ALU este determinată în primul rând de complexitatea operaţiilor aritmetice ale instrucţiunilor din setul de instrucţiuni, însă depinde, uneori semnificativ, şi de performanţele avute în vedere (viteză, paralelism, consum redus) ce pot modifica radical structura aleasă.&lt;br /&gt;
La nivel funcţional, fără a fi preocupaţi de implementarea efectivă, ALU poate fi privit ca un bloc multifuncţional a cărui funcţie este selectată de codul operaţiei instrucţiunii:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(opcode)&lt;br /&gt;
    4&amp;#039;b0001: result = operand1 + operand2;&lt;br /&gt;
    4&amp;#039;b0010: result = operand1 - operand2;&lt;br /&gt;
    // urmeaza implementarea altor operatii&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Descrieți funcțional (comportamental) un ALU de 8 biți ce execută operațiile din tabelul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab1_alu.png]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&lt;br /&gt;
|+ Tabelul 1&lt;br /&gt;
! mnemonica !! operație !! opcode !! detalii&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ADD&amp;lt;/code&amp;gt; || adunare  || 4&amp;#039;b0001 ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SUB&amp;lt;/code&amp;gt; || scădere  || 4&amp;#039;b0010 || operandul 2 se scade din operandul 1&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;AND&amp;lt;/code&amp;gt; || ȘI logic || 4&amp;#039;b0011 || fiecare bit al rezultatului este ȘI logic între biții corespunzători ai operanzilor&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;OR&amp;lt;/code&amp;gt; || SAU logic || 4&amp;#039;b0100 || fiecare bit al rezultatului este SAU logic între biții corespunzători ai operanzilor&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;XOR&amp;lt;/code&amp;gt; || XOR logic || 4&amp;#039;b0101 || fiecare bit al rezultatului este SAU-EXCLUSIV logic între biții corespunzători ai operanzilor&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;CMP&amp;lt;/code&amp;gt; || comparație  ||  4&amp;#039;b0111 || Z și N se modifică conform tabelului 2&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;LOAD&amp;lt;/code&amp;gt; || transfer ||  4&amp;#039;b1001 || operandul2 este transferat la ieșirea ALU&lt;br /&gt;
|- &lt;br /&gt;
| &amp;lt;code&amp;gt;STORE&amp;lt;/code&amp;gt; || transfer ||  4&amp;#039;b1010 || operandul2 este transferat la ieșirea ALU&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Tabelul 1 nu conține toate instrucțiunile setului de instrucțiuni, ci numai instrucțiunile care folosesc ALU. Pentru instrucțiunile ce nu folosesc ALU implementarea execuției lor în ALU poate fi ignorată, dar rezultatul de la ieșirea ALU nu trebuie scris în vreun registru.&lt;br /&gt;
&lt;br /&gt;
Rezultatul operației de comparație este semnalizat prin biții indicatori ai rezultatului:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&lt;br /&gt;
|+ Tabelul 2&lt;br /&gt;
! !! Z !! N&lt;br /&gt;
|-&lt;br /&gt;
| operand1 &amp;gt; operand2 || 0  || 0&lt;br /&gt;
|-&lt;br /&gt;
| operand1 = operand2 || 1  || 0&lt;br /&gt;
|-&lt;br /&gt;
| operand1 &amp;lt; operand2 || 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Biții indicatori sunt calculați pentru fiecare operație și reflectă starea rezultatului. Procesorul implementat în laborator are doi indicatori, &amp;#039;&amp;#039;&amp;#039;Z&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;N&amp;#039;&amp;#039;&amp;#039;. Dacă rezultatul este zero se activează bitul &amp;#039;&amp;#039;&amp;#039;Z&amp;#039;&amp;#039;&amp;#039; (zero). Dacă rezultatul este negativ se activează ieșirea &amp;#039;&amp;#039;&amp;#039;N&amp;#039;&amp;#039;&amp;#039; (negativ). Operația de comparație poate fi implementată ca o operație de scădere fără destinație (se salvează în procesor doar biții indicatori nu și rezultatul):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign Z = (result == 0);&lt;br /&gt;
assign N = result[7]; // în complement față de 2 bitul MSB este bit de semn&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== REGS ===&lt;br /&gt;
&lt;br /&gt;
Setul de registre are 16 registre de 8 biți. Fiecare registru poate fi sursa oricărui operand și poate fi destinație.&lt;br /&gt;
Setul de registre poate avea porturi distincte pentru scriere și pentru citire, precum și porturi separate pentru fiecare operand citit.&lt;br /&gt;
Implementarea aleasă pentru acest laborator are un set de registre cu trei porturi, un port pentru citirea primului operand (&amp;#039;&amp;#039;&amp;#039;raddr1&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;rdata1&amp;#039;&amp;#039;&amp;#039;), altul pentru citirea celui de al doilea operand (&amp;#039;&amp;#039;&amp;#039;raddr2&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;rdata2&amp;#039;&amp;#039;&amp;#039;) și un port pentru scriere (&amp;#039;&amp;#039;&amp;#039;waddr&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039;). Portul de scriere folosește un semnal de control, &amp;#039;&amp;#039;&amp;#039;wen&amp;#039;&amp;#039;&amp;#039;, ce activează scrierea numai pentru anumite instrucțiuni. Pentru accesul la un registru este nevoie de o adresă de 4 biți. Semnalele de adresă &amp;#039;&amp;#039;&amp;#039;raddr1&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;raddr2&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;waddr&amp;#039;&amp;#039;&amp;#039; sunt de 4 biți. Datele sunt pe 8 biți, prin urmare registrele, ieșirile de date &amp;#039;&amp;#039;&amp;#039;rdata1&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;rdata2&amp;#039;&amp;#039;&amp;#039;, dar și intrarea de date &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; sunt fiecare de câte 8 biți.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab1_regs.png]]&lt;br /&gt;
&lt;br /&gt;
Scrierea în setul de registre este secvențială, pe frontul semnalului de ceas de la intrarea &amp;#039;&amp;#039;&amp;#039;clk&amp;#039;&amp;#039;&amp;#039; (nereprezentată în figura de mai sus).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
logic [7:0] registru [0:15]; // set de 16 registre a câte 8 biți fiecare&lt;br /&gt;
&lt;br /&gt;
// portul de scriere&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(wen) registru[waddr] &amp;lt;= wdata; // scriere sincronă - pe ceas - a valorii de la intrarea de date wdata în registrul destinație&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
// portul 1 de citire&lt;br /&gt;
assign rdata1 = registru[raddr1]; // ieșirea rdata1 este valoarea din registrul cu numărul raddr1&lt;br /&gt;
// portul 2 de citire&lt;br /&gt;
                                  // &amp;lt;- completați codul&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RALU ===&lt;br /&gt;
&lt;br /&gt;
Unitatea aritmetico-logică împreună cu setul de registre formează RALU (Register and ALU).&lt;br /&gt;
&lt;br /&gt;
[[Fișier: asc_lab1_ralu.png]]&lt;br /&gt;
&lt;br /&gt;
=== validare RALU ===&lt;br /&gt;
&lt;br /&gt;
Scrieti un modul de testare ce instanțiază setul de registre și ALU, generează ceasul, semnalul de reset și o secvență de instrucțiuni.&lt;br /&gt;
&lt;br /&gt;
==== generarea ceasului ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin&lt;br /&gt;
    clk = 0;                 // initialization at time 0&lt;br /&gt;
    forever #10 clk = ~clk;  // toggle the clock at each 10 simulation steps&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== generarea semnalului de reset ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin&lt;br /&gt;
    rst = 0;&lt;br /&gt;
    #13 rst = 1; // reset activ în 1 logic&lt;br /&gt;
    #20 rst = 0;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Întîrzierile sunt alese astfel încât fronturile semnalului de reset să nu coincidă cu fronturile ceasului.&lt;br /&gt;
&lt;br /&gt;
==== generarea secvenței de instrucțiuni ====&lt;br /&gt;
&lt;br /&gt;
La fiecare ceas se setează valorile intrărilor &amp;#039;&amp;#039;&amp;#039;opcode&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;sursa1&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;sursa2&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;dest&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;wen&amp;#039;&amp;#039;&amp;#039; cu valori care să corespundă instrucțiunii dorite.&lt;br /&gt;
Pentru a ne asigura că toate semnalele se modifică numai după frontul activ al ceasului, vom aștepta de fiecare dată acest front folosind instrucțiunea &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;@(posedge clk);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Semnalul &amp;#039;&amp;#039;&amp;#039;wen&amp;#039;&amp;#039;&amp;#039; se setează la &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; sau la &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; după cum dorim ca &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; să se salveze sau nu în registrul destinație.&lt;br /&gt;
Semnalul &amp;#039;&amp;#039;&amp;#039;wen&amp;#039;&amp;#039;&amp;#039; nu face parte din instrucțiune. În laboratorul 2 el va fi generat de unitatea de control a procesorului (UCP) în funcție de codul instrucțiunii. De exemplu instrucțiunea CMP nu modifică niciun registru ci doar biții indicatori, prin urmare &amp;#039;&amp;#039;&amp;#039;wen&amp;#039;&amp;#039;&amp;#039; va fi în permanență &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; pe durata procesării acestei instrucțiuni.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin&lt;br /&gt;
    opcode = 4&amp;#039;b0000; dest = 4&amp;#039;d0; sursa1 = 4&amp;#039;d0; sursa2 = 4&amp;#039;d0; wen = 1&amp;#039;b0;&lt;br /&gt;
    #26 // se așteaptă finalizarea resetului&lt;br /&gt;
    @(posedge clk);&lt;br /&gt;
    opcode = 4&amp;#039;b0001; dest = 4&amp;#039;d7; sursa1 = 4&amp;#039;d6; sursa2 = 4&amp;#039;d5; wen = 1&amp;#039;b1; // ADD R7 R6 R5 // R7 &amp;lt;- R6 + R5&lt;br /&gt;
    @(posedge clk);&lt;br /&gt;
    opcode = 4&amp;#039;b0010; dest = 4&amp;#039;d7; sursa1 = 4&amp;#039;d7; sursa2 = 4&amp;#039;d4; wen = 1&amp;#039;b1; // SUB R7 R7 R4 // R7 &amp;lt;- R7 - R4&lt;br /&gt;
    // alte instrucțiuni&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== initializarea valorilor in registre ===&lt;br /&gt;
&lt;br /&gt;
Se poate face a) la reset, dacă modulul are intrare de reset, sau b)  într-un bloc &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; folosit doar pentru simulare.&lt;br /&gt;
&lt;br /&gt;
a)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(rst) begin&lt;br /&gt;
        registru[0] = 13;&lt;br /&gt;
        . . . &lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        if(wen) . . .&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
b)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin&lt;br /&gt;
    registru[0] = 13;&lt;br /&gt;
    registru[1] = 27;&lt;br /&gt;
    . . . .&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dacă blocul &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; este scris în modulul de testare iar variabilele inițializate sunt din interiorul modului testat sau chiar dintr-un submodul al acestuia, numele acestora trebuie să fie complet, corespunzător ierarhiei.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
    ralu.regs.registru[0] = 13;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Advanced_Digital_Systems&amp;diff=8113</id>
		<title>Advanced Digital Systems</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Advanced_Digital_Systems&amp;diff=8113"/>
		<updated>2025-05-28T15:13:57Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [https://users.dcae.pub.ro/~zhascsi/courses/add/add2.pdf Structured design with verilog]&lt;br /&gt;
* [https://users.dcae.pub.ro/~zhascsi/courses/add/add3.pdf Carry Lookahead Adder - iterative design]&lt;br /&gt;
* [https://users.dcae.pub.ro/~zhascsi/courses/add/add4.pdf Carry Lookahead Adder - recursive design]&lt;br /&gt;
&lt;br /&gt;
== Test code for adder ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
module test;&lt;br /&gt;
&lt;br /&gt;
logic [31:0] a;&lt;br /&gt;
logic [31:0] b;&lt;br /&gt;
logic [32:0] s;&lt;br /&gt;
&lt;br /&gt;
cla   #(32) dut (.a(a), .b(b), .s(s));&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    repeat(100) begin&lt;br /&gt;
        #1&lt;br /&gt;
        a  = $random;&lt;br /&gt;
        b  = $random;&lt;br /&gt;
        #1&lt;br /&gt;
        if(s !== a + b)&lt;br /&gt;
            $display(&amp;quot;ERROR\n&amp;quot;);&lt;br /&gt;
        else&lt;br /&gt;
            $display(&amp;quot;OK\n&amp;quot;);&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Projects ==&lt;br /&gt;
&lt;br /&gt;
# [[MD5 Hash]]&lt;br /&gt;
# [[SHA-1 Hash]]&lt;br /&gt;
# [[SHA-256 Hash]]&lt;br /&gt;
# [[SHA-512 Hash]]&lt;br /&gt;
# [[AES Encryption]]&lt;br /&gt;
# [[DES Encryption]]&lt;br /&gt;
# [[RSA Encryption]]&lt;br /&gt;
# [[RC4 Stream Cypher]]&lt;br /&gt;
# [[Sorting Network]]&lt;br /&gt;
# [[Sum of Absolute Differences]]&lt;br /&gt;
# [[Sum of Squared Differences]]&lt;br /&gt;
# [[Artificial Neural Network]]&lt;br /&gt;
# [[Gaussian 2D Filter]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Advanced_Digital_Systems&amp;diff=8112</id>
		<title>Advanced Digital Systems</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Advanced_Digital_Systems&amp;diff=8112"/>
		<updated>2025-05-28T14:59:48Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [https://users.dcae.pub.ro/~zhascsi/courses/add/add2.pdf Structured design with verilog]&lt;br /&gt;
* [https://users.dcae.pub.ro/~zhascsi/courses/add/add3.pdf Carry Lookahead Adder - iterative design]&lt;br /&gt;
* [https://users.dcae.pub.ro/~zhascsi/courses/add/add4.pdf Carry Lookahead Adder - recursive design]&lt;br /&gt;
&lt;br /&gt;
== Projects ==&lt;br /&gt;
&lt;br /&gt;
# [[MD5 Hash]]&lt;br /&gt;
# [[SHA-1 Hash]]&lt;br /&gt;
# [[SHA-256 Hash]]&lt;br /&gt;
# [[SHA-512 Hash]]&lt;br /&gt;
# [[AES Encryption]]&lt;br /&gt;
# [[DES Encryption]]&lt;br /&gt;
# [[RSA Encryption]]&lt;br /&gt;
# [[RC4 Stream Cypher]]&lt;br /&gt;
# [[Sorting Network]]&lt;br /&gt;
# [[Sum of Absolute Differences]]&lt;br /&gt;
# [[Sum of Squared Differences]]&lt;br /&gt;
# [[Artificial Neural Network]]&lt;br /&gt;
# [[Gaussian 2D Filter]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8088</id>
		<title>Applications 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8088"/>
		<updated>2025-05-04T21:37:00Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Verification */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirement ==&lt;br /&gt;
&amp;#039;&amp;#039;Design, verify and implement a triangular sequence generator. It generates a sequence of numbers that periodically increase and decrease between two configurable limits, limith and limitl. The sequence rate is one number per second. The binary sequence of numbers, &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;, is outputted for display as &amp;#039;&amp;#039;&amp;#039;seg_bcd&amp;#039;&amp;#039;&amp;#039;. Figure 1 shows an example of triangular sequence that varies between 6 and 9. The bottom waveform is the analog signal that would be generated by a DAC whose input is the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle_wave.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;The default limit values are 0 for &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and 9 for &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;, and they are set each time the reset is applied. To change the limits use the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button in this order. Set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a desired value for the low limit and push the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button to set the &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; value to &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. Then change the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value to the desired high limit and with a second push set the &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; value this new &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. The current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value is displayed through &amp;#039;&amp;#039;&amp;#039;seg_din&amp;#039;&amp;#039;&amp;#039; output. After configuration is done, the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button is ignored.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== triangle ===&lt;br /&gt;
&lt;br /&gt;
The top level design, named &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039;, has 4 sequential blocks and one dual port ROM memory (Figure 2).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: Lab10_triangle.png]]&lt;br /&gt;
&lt;br /&gt;
All sequential blocks are clocked by the same 100 MHz input clock and share the reset sinal, &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, active &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== pulsegen ===&lt;br /&gt;
&lt;br /&gt;
To easy the design of the circuit, the pulse generator, &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039;, generates a periodic sequence of pulses, at a rate of one pulse per second, each pulse lasting only one clock cycle. The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; is a counter that generates one pulse at each 10 million clock cycles. However, to make possible the verification of the circuit, this number is not given as an explicit literal in HDL description but as a parameter declared inside the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
parameter CYCLE = 100_000_000;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameter value may be changed from the testbench to much lower values, suitable for verification (otherwise the simulation will run for hours to count 100 million pulses!).&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; output, &amp;#039;&amp;#039;&amp;#039;pulse&amp;#039;&amp;#039;&amp;#039;, is used to enable the counting of the &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039; counter.&lt;br /&gt;
&lt;br /&gt;
=== cnt_bcd ===&lt;br /&gt;
&lt;br /&gt;
Whenever its &amp;#039;&amp;#039;&amp;#039;cen&amp;#039;&amp;#039;&amp;#039; input is active, it increments or decrements, according to &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; input. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; it increments. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; it decrements.&lt;br /&gt;
&lt;br /&gt;
=== fsm_cnt ===&lt;br /&gt;
&lt;br /&gt;
This automaton controls the sequence generated by &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039;, changing its direction of counting such that to keep the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence between the limits, &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;. Whenever &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value reaches one of the limits, the counting direction, &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039;, is reversed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fsm_ctrl ===&lt;br /&gt;
&lt;br /&gt;
Another automaton controls the configuration process. It keeps two registers, &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039;, whose values are changed according to the configuration protocol described above. At the reset, their values are set to the default ones, &amp;#039;&amp;#039;&amp;#039;9&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Two successive push update the values of the limits, after which the new limit values stay stable until reset. A push is completed after the button is released.&lt;br /&gt;
&lt;br /&gt;
=== rom16x8 ===&lt;br /&gt;
&lt;br /&gt;
The ROM memory is a dual port read only memory. It may be initialized through the &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; tasks with proper values for digit display. Alternatively, the initialization of the memory content may be done with an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin // the last 7 bits are the digit segment values&lt;br /&gt;
    mem[0] = 8&amp;#039;b01000000;&lt;br /&gt;
    mem[1] = 8&amp;#039;b01111001;&lt;br /&gt;
    .... // initialization for the other memory locations&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
Write a testbench with the following test scenario:&lt;br /&gt;
* apply reset&lt;br /&gt;
* wait for 100 clock cycles&lt;br /&gt;
* set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* change &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a high limit and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* let the simulation run for some other 100 clock cycles&lt;br /&gt;
&lt;br /&gt;
In the testbench module redefine the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; parameter, such that is generates a pulse at each 10 clock cycles (instead of one at each 100,000,000 cycles):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
defparam dut.pulsegen.CYCLE = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
* Use push buttons for &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039; inputs, and switches for the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; input value.&lt;br /&gt;
* Use one digit from the left display to show the current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value in decimal.&lt;br /&gt;
* Use one digit from the right display to show the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value in decimal&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
pulsegen(rst, clk, pulse) with an internal parameter named &amp;#039;&amp;#039;&amp;#039;CYCLE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
cnt_bcd(rst, clk, cen, dir, value)&lt;br /&gt;
&lt;br /&gt;
fsm_cnt(rst, clk, limith, limitl, value, dir)&lt;br /&gt;
&lt;br /&gt;
fsm_ctrl(rst, clk, push, din, limith, limitl)&lt;br /&gt;
&lt;br /&gt;
rom16x8(addra, douta, addrb, doutb)&lt;br /&gt;
&lt;br /&gt;
triangle(rst, clk, push, din, seg_din, seg_bcd)&lt;br /&gt;
&lt;br /&gt;
triangle_tb with the triangle instance name &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8087</id>
		<title>Applications 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8087"/>
		<updated>2025-05-04T21:36:18Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* pulsegen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirement ==&lt;br /&gt;
&amp;#039;&amp;#039;Design, verify and implement a triangular sequence generator. It generates a sequence of numbers that periodically increase and decrease between two configurable limits, limith and limitl. The sequence rate is one number per second. The binary sequence of numbers, &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;, is outputted for display as &amp;#039;&amp;#039;&amp;#039;seg_bcd&amp;#039;&amp;#039;&amp;#039;. Figure 1 shows an example of triangular sequence that varies between 6 and 9. The bottom waveform is the analog signal that would be generated by a DAC whose input is the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle_wave.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;The default limit values are 0 for &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and 9 for &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;, and they are set each time the reset is applied. To change the limits use the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button in this order. Set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a desired value for the low limit and push the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button to set the &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; value to &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. Then change the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value to the desired high limit and with a second push set the &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; value this new &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. The current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value is displayed through &amp;#039;&amp;#039;&amp;#039;seg_din&amp;#039;&amp;#039;&amp;#039; output. After configuration is done, the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button is ignored.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== triangle ===&lt;br /&gt;
&lt;br /&gt;
The top level design, named &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039;, has 4 sequential blocks and one dual port ROM memory (Figure 2).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: Lab10_triangle.png]]&lt;br /&gt;
&lt;br /&gt;
All sequential blocks are clocked by the same 100 MHz input clock and share the reset sinal, &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, active &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== pulsegen ===&lt;br /&gt;
&lt;br /&gt;
To easy the design of the circuit, the pulse generator, &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039;, generates a periodic sequence of pulses, at a rate of one pulse per second, each pulse lasting only one clock cycle. The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; is a counter that generates one pulse at each 10 million clock cycles. However, to make possible the verification of the circuit, this number is not given as an explicit literal in HDL description but as a parameter declared inside the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
parameter CYCLE = 100_000_000;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameter value may be changed from the testbench to much lower values, suitable for verification (otherwise the simulation will run for hours to count 100 million pulses!).&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; output, &amp;#039;&amp;#039;&amp;#039;pulse&amp;#039;&amp;#039;&amp;#039;, is used to enable the counting of the &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039; counter.&lt;br /&gt;
&lt;br /&gt;
=== cnt_bcd ===&lt;br /&gt;
&lt;br /&gt;
Whenever its &amp;#039;&amp;#039;&amp;#039;cen&amp;#039;&amp;#039;&amp;#039; input is active, it increments or decrements, according to &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; input. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; it increments. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; it decrements.&lt;br /&gt;
&lt;br /&gt;
=== fsm_cnt ===&lt;br /&gt;
&lt;br /&gt;
This automaton controls the sequence generated by &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039;, changing its direction of counting such that to keep the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence between the limits, &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;. Whenever &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value reaches one of the limits, the counting direction, &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039;, is reversed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fsm_ctrl ===&lt;br /&gt;
&lt;br /&gt;
Another automaton controls the configuration process. It keeps two registers, &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039;, whose values are changed according to the configuration protocol described above. At the reset, their values are set to the default ones, &amp;#039;&amp;#039;&amp;#039;9&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Two successive push update the values of the limits, after which the new limit values stay stable until reset. A push is completed after the button is released.&lt;br /&gt;
&lt;br /&gt;
=== rom16x8 ===&lt;br /&gt;
&lt;br /&gt;
The ROM memory is a dual port read only memory. It may be initialized through the &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; tasks with proper values for digit display. Alternatively, the initialization of the memory content may be done with an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin // the last 7 bits are the digit segment values&lt;br /&gt;
    mem[0] = 8&amp;#039;b01000000;&lt;br /&gt;
    mem[1] = 8&amp;#039;b01111001;&lt;br /&gt;
    .... // initialization for the other memory locations&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
Write a testbench with the following test scenario:&lt;br /&gt;
* apply reset&lt;br /&gt;
* wait for 100 clock cycles&lt;br /&gt;
* set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* change &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a high limit and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* let the simulation run for some other 100 clock cycles&lt;br /&gt;
&lt;br /&gt;
In the testbench module redefine the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; parameter, such that is generates a pulse at each 5 clock cycles (instead of one at each 50,000,000 cycles):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
defparam dut.pulsegen.CYCLE = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
* Use push buttons for &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039; inputs, and switches for the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; input value.&lt;br /&gt;
* Use one digit from the left display to show the current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value in decimal.&lt;br /&gt;
* Use one digit from the right display to show the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value in decimal&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
pulsegen(rst, clk, pulse) with an internal parameter named &amp;#039;&amp;#039;&amp;#039;CYCLE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
cnt_bcd(rst, clk, cen, dir, value)&lt;br /&gt;
&lt;br /&gt;
fsm_cnt(rst, clk, limith, limitl, value, dir)&lt;br /&gt;
&lt;br /&gt;
fsm_ctrl(rst, clk, push, din, limith, limitl)&lt;br /&gt;
&lt;br /&gt;
rom16x8(addra, douta, addrb, doutb)&lt;br /&gt;
&lt;br /&gt;
triangle(rst, clk, push, din, seg_din, seg_bcd)&lt;br /&gt;
&lt;br /&gt;
triangle_tb with the triangle instance name &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8086</id>
		<title>Applications 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8086"/>
		<updated>2025-05-04T21:34:22Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Interfaces */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirement ==&lt;br /&gt;
&amp;#039;&amp;#039;Design, verify and implement a triangular sequence generator. It generates a sequence of numbers that periodically increase and decrease between two configurable limits, limith and limitl. The sequence rate is one number per second. The binary sequence of numbers, &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;, is outputted for display as &amp;#039;&amp;#039;&amp;#039;seg_bcd&amp;#039;&amp;#039;&amp;#039;. Figure 1 shows an example of triangular sequence that varies between 6 and 9. The bottom waveform is the analog signal that would be generated by a DAC whose input is the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle_wave.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;The default limit values are 0 for &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and 9 for &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;, and they are set each time the reset is applied. To change the limits use the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button in this order. Set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a desired value for the low limit and push the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button to set the &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; value to &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. Then change the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value to the desired high limit and with a second push set the &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; value this new &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. The current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value is displayed through &amp;#039;&amp;#039;&amp;#039;seg_din&amp;#039;&amp;#039;&amp;#039; output. After configuration is done, the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button is ignored.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== triangle ===&lt;br /&gt;
&lt;br /&gt;
The top level design, named &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039;, has 4 sequential blocks and one dual port ROM memory (Figure 2).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: Lab10_triangle.png]]&lt;br /&gt;
&lt;br /&gt;
All sequential blocks are clocked by the same 100 MHz input clock and share the reset sinal, &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, active &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== pulsegen ===&lt;br /&gt;
&lt;br /&gt;
To easy the design of the circuit, the pulse generator, &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039;, generates a periodic sequence of pulses, at a rate of one pulse per second, each pulse lasting only one clock cycle. The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; is a counter that generates one pulse at each 10 million clock cycles. However, to make possible the verification of the circuit, this number is not given as an explicit literal in HDL description but as a parameter declared inside the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
parameter CYCLE = 100_000_000;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameter value may be changed from the testbench to much lower values, suitable for verification (otherwise the simulation will run for hours to count 50 million pulses!).&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; output, &amp;#039;&amp;#039;&amp;#039;pulse&amp;#039;&amp;#039;&amp;#039;, is used to enable the counting of the &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039; counter.&lt;br /&gt;
&lt;br /&gt;
=== cnt_bcd ===&lt;br /&gt;
&lt;br /&gt;
Whenever its &amp;#039;&amp;#039;&amp;#039;cen&amp;#039;&amp;#039;&amp;#039; input is active, it increments or decrements, according to &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; input. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; it increments. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; it decrements.&lt;br /&gt;
&lt;br /&gt;
=== fsm_cnt ===&lt;br /&gt;
&lt;br /&gt;
This automaton controls the sequence generated by &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039;, changing its direction of counting such that to keep the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence between the limits, &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;. Whenever &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value reaches one of the limits, the counting direction, &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039;, is reversed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fsm_ctrl ===&lt;br /&gt;
&lt;br /&gt;
Another automaton controls the configuration process. It keeps two registers, &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039;, whose values are changed according to the configuration protocol described above. At the reset, their values are set to the default ones, &amp;#039;&amp;#039;&amp;#039;9&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Two successive push update the values of the limits, after which the new limit values stay stable until reset. A push is completed after the button is released.&lt;br /&gt;
&lt;br /&gt;
=== rom16x8 ===&lt;br /&gt;
&lt;br /&gt;
The ROM memory is a dual port read only memory. It may be initialized through the &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; tasks with proper values for digit display. Alternatively, the initialization of the memory content may be done with an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin // the last 7 bits are the digit segment values&lt;br /&gt;
    mem[0] = 8&amp;#039;b01000000;&lt;br /&gt;
    mem[1] = 8&amp;#039;b01111001;&lt;br /&gt;
    .... // initialization for the other memory locations&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
Write a testbench with the following test scenario:&lt;br /&gt;
* apply reset&lt;br /&gt;
* wait for 100 clock cycles&lt;br /&gt;
* set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* change &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a high limit and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* let the simulation run for some other 100 clock cycles&lt;br /&gt;
&lt;br /&gt;
In the testbench module redefine the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; parameter, such that is generates a pulse at each 5 clock cycles (instead of one at each 50,000,000 cycles):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
defparam dut.pulsegen.CYCLE = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
* Use push buttons for &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039; inputs, and switches for the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; input value.&lt;br /&gt;
* Use one digit from the left display to show the current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value in decimal.&lt;br /&gt;
* Use one digit from the right display to show the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value in decimal&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
pulsegen(rst, clk, pulse) with an internal parameter named &amp;#039;&amp;#039;&amp;#039;CYCLE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
cnt_bcd(rst, clk, cen, dir, value)&lt;br /&gt;
&lt;br /&gt;
fsm_cnt(rst, clk, limith, limitl, value, dir)&lt;br /&gt;
&lt;br /&gt;
fsm_ctrl(rst, clk, push, din, limith, limitl)&lt;br /&gt;
&lt;br /&gt;
rom16x8(addra, douta, addrb, doutb)&lt;br /&gt;
&lt;br /&gt;
triangle(rst, clk, push, din, seg_din, seg_bcd)&lt;br /&gt;
&lt;br /&gt;
triangle_tb with the triangle instance name &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8085</id>
		<title>Applications 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8085"/>
		<updated>2025-05-04T21:32:08Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirement ==&lt;br /&gt;
&amp;#039;&amp;#039;Design, verify and implement a triangular sequence generator. It generates a sequence of numbers that periodically increase and decrease between two configurable limits, limith and limitl. The sequence rate is one number per second. The binary sequence of numbers, &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;, is outputted for display as &amp;#039;&amp;#039;&amp;#039;seg_bcd&amp;#039;&amp;#039;&amp;#039;. Figure 1 shows an example of triangular sequence that varies between 6 and 9. The bottom waveform is the analog signal that would be generated by a DAC whose input is the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle_wave.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;The default limit values are 0 for &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and 9 for &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;, and they are set each time the reset is applied. To change the limits use the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button in this order. Set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a desired value for the low limit and push the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button to set the &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; value to &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. Then change the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value to the desired high limit and with a second push set the &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; value this new &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. The current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value is displayed through &amp;#039;&amp;#039;&amp;#039;seg_din&amp;#039;&amp;#039;&amp;#039; output. After configuration is done, the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button is ignored.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== triangle ===&lt;br /&gt;
&lt;br /&gt;
The top level design, named &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039;, has 4 sequential blocks and one dual port ROM memory (Figure 2).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: Lab10_triangle.png]]&lt;br /&gt;
&lt;br /&gt;
All sequential blocks are clocked by the same 100 MHz input clock and share the reset sinal, &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, active &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== pulsegen ===&lt;br /&gt;
&lt;br /&gt;
To easy the design of the circuit, the pulse generator, &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039;, generates a periodic sequence of pulses, at a rate of one pulse per second, each pulse lasting only one clock cycle. The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; is a counter that generates one pulse at each 10 million clock cycles. However, to make possible the verification of the circuit, this number is not given as an explicit literal in HDL description but as a parameter declared inside the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
parameter CYCLE = 100_000_000;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameter value may be changed from the testbench to much lower values, suitable for verification (otherwise the simulation will run for hours to count 50 million pulses!).&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; output, &amp;#039;&amp;#039;&amp;#039;pulse&amp;#039;&amp;#039;&amp;#039;, is used to enable the counting of the &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039; counter.&lt;br /&gt;
&lt;br /&gt;
=== cnt_bcd ===&lt;br /&gt;
&lt;br /&gt;
Whenever its &amp;#039;&amp;#039;&amp;#039;cen&amp;#039;&amp;#039;&amp;#039; input is active, it increments or decrements, according to &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; input. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; it increments. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; it decrements.&lt;br /&gt;
&lt;br /&gt;
=== fsm_cnt ===&lt;br /&gt;
&lt;br /&gt;
This automaton controls the sequence generated by &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039;, changing its direction of counting such that to keep the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence between the limits, &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;. Whenever &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value reaches one of the limits, the counting direction, &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039;, is reversed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fsm_ctrl ===&lt;br /&gt;
&lt;br /&gt;
Another automaton controls the configuration process. It keeps two registers, &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039;, whose values are changed according to the configuration protocol described above. At the reset, their values are set to the default ones, &amp;#039;&amp;#039;&amp;#039;9&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Two successive push update the values of the limits, after which the new limit values stay stable until reset. A push is completed after the button is released.&lt;br /&gt;
&lt;br /&gt;
=== rom16x8 ===&lt;br /&gt;
&lt;br /&gt;
The ROM memory is a dual port read only memory. It may be initialized through the &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; tasks with proper values for digit display. Alternatively, the initialization of the memory content may be done with an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin // the last 7 bits are the digit segment values&lt;br /&gt;
    mem[0] = 8&amp;#039;b01000000;&lt;br /&gt;
    mem[1] = 8&amp;#039;b01111001;&lt;br /&gt;
    .... // initialization for the other memory locations&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
Write a testbench with the following test scenario:&lt;br /&gt;
* apply reset&lt;br /&gt;
* wait for 100 clock cycles&lt;br /&gt;
* set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* change &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a high limit and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* let the simulation run for some other 100 clock cycles&lt;br /&gt;
&lt;br /&gt;
In the testbench module redefine the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; parameter, such that is generates a pulse at each 5 clock cycles (instead of one at each 50,000,000 cycles):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
defparam dut.pulsegen.CYCLE = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
* Use push buttons for &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039; inputs, and switches for the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; input value.&lt;br /&gt;
* Use one digit from the left display to show the current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value in decimal.&lt;br /&gt;
* Use one digit from the right display to show the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value in decimal&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
pulsegen(rst, clk, pulse) with an internal parameter named &amp;#039;&amp;#039;&amp;#039;CYCLE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
cnt_bcd(rst, clk, cen, dir, value)&lt;br /&gt;
&lt;br /&gt;
fsm_cnt(rst, clk, limith, limitl, value, dir)&lt;br /&gt;
&lt;br /&gt;
fsm_ctrl(rst, clk, push, din, limith, limitl)&lt;br /&gt;
&lt;br /&gt;
rom16x8(addra, douta, addrb, doutb)&lt;br /&gt;
&lt;br /&gt;
triangle(rst, clk, push, din, seg_din, seg_bcd) with the pulsegen instance name &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; and a 4 bit connection named &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
triangle_tb with the triangle instance name &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8084</id>
		<title>Applications 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8084"/>
		<updated>2025-05-04T21:31:49Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirement ==&lt;br /&gt;
&amp;#039;&amp;#039;Design, verify and implement a triangular sequence generator. It generates a sequence of numbers that periodically increase and decrease between two configurable limits, limith and limitl. The sequence rate is one number per second. The binary sequence of numbers, &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;, is outputted for display as &amp;#039;&amp;#039;&amp;#039;seg_bcd&amp;#039;&amp;#039;&amp;#039;. Figure 1 shows an example of triangular sequence that varies between 6 and 9. The bottom waveform is the analog signal that would be generated by a DAC whose input is the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle_wave.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;The default limit values are 0 for &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and 9 for &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;, and they are set each time the reset is applied. To change the limits use the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button in this order. Set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a desired value for the low limit and push the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button to set the &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; value to &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. Then change the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value to the desired high limit and with a second push set the &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; value this new &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. The current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value is displayed through &amp;#039;&amp;#039;&amp;#039;seg_din&amp;#039;&amp;#039;&amp;#039; output. After configuration is done, the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button is ignored.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== triangle ===&lt;br /&gt;
&lt;br /&gt;
The top level design, named &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039;, has 4 sequential blocks and one dual port ROM memory (Figure 2).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: Lab10_triangle.png]]&lt;br /&gt;
&lt;br /&gt;
All sequential blocks are clocked by the same 100 MHz input clock and share the reset sinal, &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, active &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== pulsegen ===&lt;br /&gt;
&lt;br /&gt;
To easy the design of the circuit, the pulse generator, &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039;, generates a periodic sequence of pulses, at a rate of one pulse per second, each pulse lasting only one clock cycle. The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; is a counter that generates one pulse at each 10 million clock cycles. However, to make possible the verification of the circuit, this number is not given as an explicit literal in HDL description but as a parameter declared inside the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
parameter CYCLE = 100_000_000;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameter value may be changed from the testbench to much lower values, suitable for verification (otherwise the simulation will run for hours to count 50 million pulses!).&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; output, &amp;#039;&amp;#039;&amp;#039;pulse&amp;#039;&amp;#039;&amp;#039;, is used to enable the counting of the &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039; counter.&lt;br /&gt;
&lt;br /&gt;
=== cnt_bcd ===&lt;br /&gt;
&lt;br /&gt;
Whenever its &amp;#039;&amp;#039;&amp;#039;cen&amp;#039;&amp;#039;&amp;#039; input is active, it increments or decrements, according to &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; input. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; it increments. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; it decrements.&lt;br /&gt;
&lt;br /&gt;
=== fsm_cnt ===&lt;br /&gt;
&lt;br /&gt;
This automaton controls the sequence generated by &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039;, changing its direction of counting such that to keep the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence between the limits, &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;. Whenever &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value reaches one of the limits, the counting direction, &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039;, is reversed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fsm_ctrl ===&lt;br /&gt;
&lt;br /&gt;
Another automaton controls the configuration process. It keeps two registers, &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039;, whose values are changed according to the configuration protocol described above. At the reset, their values are set to the default ones, &amp;#039;&amp;#039;&amp;#039;9&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Two successive push update the values of the limits, after which the new limit values stay stable until reset. A push is completed after the button is released.&lt;br /&gt;
&lt;br /&gt;
=== rom16x8 ===&lt;br /&gt;
&lt;br /&gt;
The ROM memory is a dual port read only memory. It may be initialized through the &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; tasks with proper values for digit display. Alternatively, the initialization of the memory content may be done with an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin // the last 7 bits are the digit segment values&lt;br /&gt;
    mem[0] = 8&amp;#039;b01000000;&lt;br /&gt;
    mem[1] = 8&amp;#039;b01111001;&lt;br /&gt;
    .... // initialization for the other memory locations&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
Write a testbench with the following test scenario:&lt;br /&gt;
* apply reset&lt;br /&gt;
* wait for 100 clock cycles&lt;br /&gt;
* set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* change &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a high limit and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* let the simulation run for some other 100 clock cycles&lt;br /&gt;
&lt;br /&gt;
In the testbench module redefine the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; parameter, such that is generates a pulse at each 5 clock cycles (instead of one at each 50,000,000 cycles):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
defparam dut.pulsegen.CYCLE = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
Use push buttons for &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039; inputs, and switches for the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; input value.&lt;br /&gt;
Use one digit from the left display to show the current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value in decimal.&lt;br /&gt;
Use one digit from the right display to show the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value in decimal&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
pulsegen(rst, clk, pulse) with an internal parameter named &amp;#039;&amp;#039;&amp;#039;CYCLE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
cnt_bcd(rst, clk, cen, dir, value)&lt;br /&gt;
&lt;br /&gt;
fsm_cnt(rst, clk, limith, limitl, value, dir)&lt;br /&gt;
&lt;br /&gt;
fsm_ctrl(rst, clk, push, din, limith, limitl)&lt;br /&gt;
&lt;br /&gt;
rom16x8(addra, douta, addrb, doutb)&lt;br /&gt;
&lt;br /&gt;
triangle(rst, clk, push, din, seg_din, seg_bcd) with the pulsegen instance name &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; and a 4 bit connection named &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
triangle_tb with the triangle instance name &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Digital_Integrated_Circuits_(lab)&amp;diff=8083</id>
		<title>Digital Integrated Circuits (lab)</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Digital_Integrated_Circuits_(lab)&amp;diff=8083"/>
		<updated>2025-05-04T21:29:33Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# [[Applications 1 | Laboratory 1]]&lt;br /&gt;
# [[Applications 2 | Laboratory 2]]&lt;br /&gt;
# [[Applications 3 | Laboratory 3]]&lt;br /&gt;
# [[Applications 4 | Laboratory 4]]&lt;br /&gt;
# [[Applications 5 | Laboratory 5]]&lt;br /&gt;
# Test 1&lt;br /&gt;
# [[Applications 6 | Laboratory 6]]&lt;br /&gt;
# [[Applications 7 | Laboratory 7]]&lt;br /&gt;
# [[Applications 8 | Laboratory 8]]&lt;br /&gt;
# [[Applications 9 | Laboratory 9]]&lt;br /&gt;
# [[Applications 10 | Laboratory 10]]&lt;br /&gt;
&lt;br /&gt;
== Verilog Tutorials ==&lt;br /&gt;
* [http://www.asic-world.com/verilog/veritut.html Verilog Tutorial] from ASIC World&lt;br /&gt;
* [http://chipverify.com/verilog/verilog-tutorial Verilog Tutorial] from Chip Verify&lt;br /&gt;
* [http://www.emmelmann.org/Library/Tutorials/docs/verilog_ref_guide/vlog_ref_top.html Verilog reference guide]&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
* [https://www.xilinx.com/products/design-tools/vivado/vivado-ml.html Vivado™ ML Standard Edition free]&lt;br /&gt;
* [https://wiki.dcae.pub.ro/images/2/24/VivadoNewProjectTutorial.pdf Vivado New Project Tutorial]&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
[https://www.realdigital.org/hardware/boolean Boolean Board] from RealDigital&lt;br /&gt;
* [https://www.realdigital.org/doc/02013cd17602c8af749f00561f88ae21 Boolean Board - user manual]&lt;br /&gt;
* [[Boolean Board - Pinout]]&lt;br /&gt;
To implement a circuit on Boolean Board you should select the following target device in Project Settings: &amp;#039;&amp;#039;&amp;#039;xc7s50csga324-1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
* [https://dpoauwgwqsy2x.cloudfront.net/Download/pynqz2_user_manual_v1_0.pdf Pynq-Z2 - user manual]&lt;br /&gt;
* [[Pynq-Z2 - Pinout]]&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8082</id>
		<title>Applications 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8082"/>
		<updated>2025-05-04T21:26:55Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* triangle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirement ==&lt;br /&gt;
&amp;#039;&amp;#039;Design, verify and implement a triangular sequence generator. It generates a sequence of numbers that periodically increase and decrease between two configurable limits, limith and limitl. The sequence rate is one number per second. The binary sequence of numbers, &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;, is outputted for display as &amp;#039;&amp;#039;&amp;#039;seg_bcd&amp;#039;&amp;#039;&amp;#039;. Figure 1 shows an example of triangular sequence that varies between 6 and 9. The bottom waveform is the analog signal that would be generated by a DAC whose input is the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle_wave.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;The default limit values are 0 for &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and 9 for &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;, and they are set each time the reset is applied. To change the limits use the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button in this order. Set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a desired value for the low limit and push the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button to set the &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; value to &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. Then change the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value to the desired high limit and with a second push set the &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; value this new &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. The current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value is displayed through &amp;#039;&amp;#039;&amp;#039;seg_din&amp;#039;&amp;#039;&amp;#039; output. After configuration is done, the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button is ignored.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== triangle ===&lt;br /&gt;
&lt;br /&gt;
The top level design, named &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039;, has 4 sequential blocks and one dual port ROM memory (Figure 2).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: Lab10_triangle.png]]&lt;br /&gt;
&lt;br /&gt;
All sequential blocks are clocked by the same 100 MHz input clock and share the reset sinal, &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, active &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== pulsegen ===&lt;br /&gt;
&lt;br /&gt;
To easy the design of the circuit, the pulse generator, &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039;, generates a periodic sequence of pulses, at a rate of one pulse per second, each pulse lasting only one clock cycle. The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; is a counter that generates one pulse at each 10 million clock cycles. However, to make possible the verification of the circuit, this number is not given as an explicit literal in HDL description but as a parameter declared inside the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
parameter CYCLE = 100_000_000;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameter value may be changed from the testbench to much lower values, suitable for verification (otherwise the simulation will run for hours to count 50 million pulses!).&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; output, &amp;#039;&amp;#039;&amp;#039;pulse&amp;#039;&amp;#039;&amp;#039;, is used to enable the counting of the &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039; counter.&lt;br /&gt;
&lt;br /&gt;
=== cnt_bcd ===&lt;br /&gt;
&lt;br /&gt;
Whenever its &amp;#039;&amp;#039;&amp;#039;cen&amp;#039;&amp;#039;&amp;#039; input is active, it increments or decrements, according to &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; input. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; it increments. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; it decrements.&lt;br /&gt;
&lt;br /&gt;
=== fsm_cnt ===&lt;br /&gt;
&lt;br /&gt;
This automaton controls the sequence generated by &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039;, changing its direction of counting such that to keep the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence between the limits, &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;. Whenever &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value reaches one of the limits, the counting direction, &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039;, is reversed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fsm_ctrl ===&lt;br /&gt;
&lt;br /&gt;
Another automaton controls the configuration process. It keeps two registers, &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039;, whose values are changed according to the configuration protocol described above. At the reset, their values are set to the default ones, &amp;#039;&amp;#039;&amp;#039;9&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Two successive push update the values of the limits, after which the new limit values stay stable until reset. A push is completed after the button is released.&lt;br /&gt;
&lt;br /&gt;
=== rom16x8 ===&lt;br /&gt;
&lt;br /&gt;
The ROM memory is a dual port read only memory. It may be initialized through the &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; tasks with proper values for digit display. Alternatively, the initialization of the memory content may be done with an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin // the last 7 bits are the digit segment values&lt;br /&gt;
    mem[0] = 8&amp;#039;b01000000;&lt;br /&gt;
    mem[1] = 8&amp;#039;b01111001;&lt;br /&gt;
    .... // initialization for the other memory locations&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
Write a testbench with the following test scenario:&lt;br /&gt;
* apply reset&lt;br /&gt;
* wait for 100 clock cycles&lt;br /&gt;
* set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* change &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a high limit and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* let the simulation run for some other 100 clock cycles&lt;br /&gt;
&lt;br /&gt;
In the testbench module redefine the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; parameter, such that is generates a pulse at each 5 clock cycles (instead of one at each 50,000,000 cycles):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
defparam dut.pulsegen.CYCLE = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
Using the recommended board display digits, push buttons, switches and clock sources (see Figure 1), implement the &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039; top-level design module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
pulsegen(rst, clk, pulse) with an internal parameter named &amp;#039;&amp;#039;&amp;#039;CYCLE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
cnt_bcd(rst, clk, cen, dir, value)&lt;br /&gt;
&lt;br /&gt;
fsm_cnt(rst, clk, limith, limitl, value, dir)&lt;br /&gt;
&lt;br /&gt;
fsm_ctrl(rst, clk, push, din, limith, limitl)&lt;br /&gt;
&lt;br /&gt;
rom16x8(addra, douta, addrb, doutb)&lt;br /&gt;
&lt;br /&gt;
triangle(rst, clk, push, din, seg_din, seg_bcd) with the pulsegen instance name &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; and a 4 bit connection named &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
triangle_tb with the triangle instance name &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Lab10_triangle.png&amp;diff=8081</id>
		<title>Fișier:Lab10 triangle.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Lab10_triangle.png&amp;diff=8081"/>
		<updated>2025-05-04T21:26:14Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8080</id>
		<title>Applications 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8080"/>
		<updated>2025-05-04T21:19:49Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Verification */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirement ==&lt;br /&gt;
&amp;#039;&amp;#039;Design, verify and implement a triangular sequence generator. It generates a sequence of numbers that periodically increase and decrease between two configurable limits, limith and limitl. The sequence rate is one number per second. The binary sequence of numbers, &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;, is outputted for display as &amp;#039;&amp;#039;&amp;#039;seg_bcd&amp;#039;&amp;#039;&amp;#039;. Figure 1 shows an example of triangular sequence that varies between 6 and 9. The bottom waveform is the analog signal that would be generated by a DAC whose input is the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle_wave.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;The default limit values are 0 for &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and 9 for &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;, and they are set each time the reset is applied. To change the limits use the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button in this order. Set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a desired value for the low limit and push the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button to set the &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; value to &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. Then change the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value to the desired high limit and with a second push set the &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; value this new &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. The current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value is displayed through &amp;#039;&amp;#039;&amp;#039;seg_din&amp;#039;&amp;#039;&amp;#039; output. After configuration is done, the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button is ignored.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== triangle ===&lt;br /&gt;
&lt;br /&gt;
The top level design, named &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039;, has 4 sequential blocks and one dual port ROM memory (Figure 2).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle.png]]&lt;br /&gt;
&lt;br /&gt;
All sequential blocks are clocked by the same 100 MHz input clock and share the reset sinal, &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, active &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== pulsegen ===&lt;br /&gt;
&lt;br /&gt;
To easy the design of the circuit, the pulse generator, &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039;, generates a periodic sequence of pulses, at a rate of one pulse per second, each pulse lasting only one clock cycle. The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; is a counter that generates one pulse at each 10 million clock cycles. However, to make possible the verification of the circuit, this number is not given as an explicit literal in HDL description but as a parameter declared inside the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
parameter CYCLE = 100_000_000;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameter value may be changed from the testbench to much lower values, suitable for verification (otherwise the simulation will run for hours to count 50 million pulses!).&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; output, &amp;#039;&amp;#039;&amp;#039;pulse&amp;#039;&amp;#039;&amp;#039;, is used to enable the counting of the &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039; counter.&lt;br /&gt;
&lt;br /&gt;
=== cnt_bcd ===&lt;br /&gt;
&lt;br /&gt;
Whenever its &amp;#039;&amp;#039;&amp;#039;cen&amp;#039;&amp;#039;&amp;#039; input is active, it increments or decrements, according to &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; input. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; it increments. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; it decrements.&lt;br /&gt;
&lt;br /&gt;
=== fsm_cnt ===&lt;br /&gt;
&lt;br /&gt;
This automaton controls the sequence generated by &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039;, changing its direction of counting such that to keep the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence between the limits, &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;. Whenever &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value reaches one of the limits, the counting direction, &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039;, is reversed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fsm_ctrl ===&lt;br /&gt;
&lt;br /&gt;
Another automaton controls the configuration process. It keeps two registers, &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039;, whose values are changed according to the configuration protocol described above. At the reset, their values are set to the default ones, &amp;#039;&amp;#039;&amp;#039;9&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Two successive push update the values of the limits, after which the new limit values stay stable until reset. A push is completed after the button is released.&lt;br /&gt;
&lt;br /&gt;
=== rom16x8 ===&lt;br /&gt;
&lt;br /&gt;
The ROM memory is a dual port read only memory. It may be initialized through the &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; tasks with proper values for digit display. Alternatively, the initialization of the memory content may be done with an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin // the last 7 bits are the digit segment values&lt;br /&gt;
    mem[0] = 8&amp;#039;b01000000;&lt;br /&gt;
    mem[1] = 8&amp;#039;b01111001;&lt;br /&gt;
    .... // initialization for the other memory locations&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
Write a testbench with the following test scenario:&lt;br /&gt;
* apply reset&lt;br /&gt;
* wait for 100 clock cycles&lt;br /&gt;
* set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* change &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a high limit and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* let the simulation run for some other 100 clock cycles&lt;br /&gt;
&lt;br /&gt;
In the testbench module redefine the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; parameter, such that is generates a pulse at each 5 clock cycles (instead of one at each 50,000,000 cycles):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
defparam dut.pulsegen.CYCLE = 10;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
Using the recommended board display digits, push buttons, switches and clock sources (see Figure 1), implement the &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039; top-level design module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
pulsegen(rst, clk, pulse) with an internal parameter named &amp;#039;&amp;#039;&amp;#039;CYCLE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
cnt_bcd(rst, clk, cen, dir, value)&lt;br /&gt;
&lt;br /&gt;
fsm_cnt(rst, clk, limith, limitl, value, dir)&lt;br /&gt;
&lt;br /&gt;
fsm_ctrl(rst, clk, push, din, limith, limitl)&lt;br /&gt;
&lt;br /&gt;
rom16x8(addra, douta, addrb, doutb)&lt;br /&gt;
&lt;br /&gt;
triangle(rst, clk, push, din, seg_din, seg_bcd) with the pulsegen instance name &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; and a 4 bit connection named &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
triangle_tb with the triangle instance name &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8079</id>
		<title>Applications 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8079"/>
		<updated>2025-05-04T21:19:26Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* rom16x8 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirement ==&lt;br /&gt;
&amp;#039;&amp;#039;Design, verify and implement a triangular sequence generator. It generates a sequence of numbers that periodically increase and decrease between two configurable limits, limith and limitl. The sequence rate is one number per second. The binary sequence of numbers, &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;, is outputted for display as &amp;#039;&amp;#039;&amp;#039;seg_bcd&amp;#039;&amp;#039;&amp;#039;. Figure 1 shows an example of triangular sequence that varies between 6 and 9. The bottom waveform is the analog signal that would be generated by a DAC whose input is the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle_wave.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;The default limit values are 0 for &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and 9 for &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;, and they are set each time the reset is applied. To change the limits use the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button in this order. Set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a desired value for the low limit and push the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button to set the &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; value to &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. Then change the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value to the desired high limit and with a second push set the &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; value this new &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. The current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value is displayed through &amp;#039;&amp;#039;&amp;#039;seg_din&amp;#039;&amp;#039;&amp;#039; output. After configuration is done, the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button is ignored.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== triangle ===&lt;br /&gt;
&lt;br /&gt;
The top level design, named &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039;, has 4 sequential blocks and one dual port ROM memory (Figure 2).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle.png]]&lt;br /&gt;
&lt;br /&gt;
All sequential blocks are clocked by the same 100 MHz input clock and share the reset sinal, &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, active &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== pulsegen ===&lt;br /&gt;
&lt;br /&gt;
To easy the design of the circuit, the pulse generator, &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039;, generates a periodic sequence of pulses, at a rate of one pulse per second, each pulse lasting only one clock cycle. The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; is a counter that generates one pulse at each 10 million clock cycles. However, to make possible the verification of the circuit, this number is not given as an explicit literal in HDL description but as a parameter declared inside the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
parameter CYCLE = 100_000_000;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameter value may be changed from the testbench to much lower values, suitable for verification (otherwise the simulation will run for hours to count 50 million pulses!).&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; output, &amp;#039;&amp;#039;&amp;#039;pulse&amp;#039;&amp;#039;&amp;#039;, is used to enable the counting of the &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039; counter.&lt;br /&gt;
&lt;br /&gt;
=== cnt_bcd ===&lt;br /&gt;
&lt;br /&gt;
Whenever its &amp;#039;&amp;#039;&amp;#039;cen&amp;#039;&amp;#039;&amp;#039; input is active, it increments or decrements, according to &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; input. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; it increments. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; it decrements.&lt;br /&gt;
&lt;br /&gt;
=== fsm_cnt ===&lt;br /&gt;
&lt;br /&gt;
This automaton controls the sequence generated by &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039;, changing its direction of counting such that to keep the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence between the limits, &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;. Whenever &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value reaches one of the limits, the counting direction, &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039;, is reversed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fsm_ctrl ===&lt;br /&gt;
&lt;br /&gt;
Another automaton controls the configuration process. It keeps two registers, &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039;, whose values are changed according to the configuration protocol described above. At the reset, their values are set to the default ones, &amp;#039;&amp;#039;&amp;#039;9&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Two successive push update the values of the limits, after which the new limit values stay stable until reset. A push is completed after the button is released.&lt;br /&gt;
&lt;br /&gt;
=== rom16x8 ===&lt;br /&gt;
&lt;br /&gt;
The ROM memory is a dual port read only memory. It may be initialized through the &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; tasks with proper values for digit display. Alternatively, the initialization of the memory content may be done with an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin // the last 7 bits are the digit segment values&lt;br /&gt;
    mem[0] = 8&amp;#039;b01000000;&lt;br /&gt;
    mem[1] = 8&amp;#039;b01111001;&lt;br /&gt;
    .... // initialization for the other memory locations&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
Write a testbench with the following test scenario:&lt;br /&gt;
* apply reset&lt;br /&gt;
* wait for 100 clock cycles&lt;br /&gt;
* set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* change &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a high limit and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* let the simulation run for some other 100 clock cycles&lt;br /&gt;
&lt;br /&gt;
In the testbench module redefine the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; parameter, such that is generates a pulse at each 5 clock cycles (instead of one at each 50,000,000 cycles):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
defparam dut.pulsegen.CYCLE = 5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
Using the recommended board display digits, push buttons, switches and clock sources (see Figure 1), implement the &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039; top-level design module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
pulsegen(rst, clk, pulse) with an internal parameter named &amp;#039;&amp;#039;&amp;#039;CYCLE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
cnt_bcd(rst, clk, cen, dir, value)&lt;br /&gt;
&lt;br /&gt;
fsm_cnt(rst, clk, limith, limitl, value, dir)&lt;br /&gt;
&lt;br /&gt;
fsm_ctrl(rst, clk, push, din, limith, limitl)&lt;br /&gt;
&lt;br /&gt;
rom16x8(addra, douta, addrb, doutb)&lt;br /&gt;
&lt;br /&gt;
triangle(rst, clk, push, din, seg_din, seg_bcd) with the pulsegen instance name &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; and a 4 bit connection named &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
triangle_tb with the triangle instance name &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8078</id>
		<title>Applications 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8078"/>
		<updated>2025-05-04T21:18:48Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* fsm_ctrl */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirement ==&lt;br /&gt;
&amp;#039;&amp;#039;Design, verify and implement a triangular sequence generator. It generates a sequence of numbers that periodically increase and decrease between two configurable limits, limith and limitl. The sequence rate is one number per second. The binary sequence of numbers, &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;, is outputted for display as &amp;#039;&amp;#039;&amp;#039;seg_bcd&amp;#039;&amp;#039;&amp;#039;. Figure 1 shows an example of triangular sequence that varies between 6 and 9. The bottom waveform is the analog signal that would be generated by a DAC whose input is the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle_wave.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;The default limit values are 0 for &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and 9 for &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;, and they are set each time the reset is applied. To change the limits use the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button in this order. Set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a desired value for the low limit and push the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button to set the &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; value to &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. Then change the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value to the desired high limit and with a second push set the &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; value this new &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. The current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value is displayed through &amp;#039;&amp;#039;&amp;#039;seg_din&amp;#039;&amp;#039;&amp;#039; output. After configuration is done, the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button is ignored.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== triangle ===&lt;br /&gt;
&lt;br /&gt;
The top level design, named &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039;, has 4 sequential blocks and one dual port ROM memory (Figure 2).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle.png]]&lt;br /&gt;
&lt;br /&gt;
All sequential blocks are clocked by the same 100 MHz input clock and share the reset sinal, &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, active &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== pulsegen ===&lt;br /&gt;
&lt;br /&gt;
To easy the design of the circuit, the pulse generator, &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039;, generates a periodic sequence of pulses, at a rate of one pulse per second, each pulse lasting only one clock cycle. The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; is a counter that generates one pulse at each 10 million clock cycles. However, to make possible the verification of the circuit, this number is not given as an explicit literal in HDL description but as a parameter declared inside the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
parameter CYCLE = 100_000_000;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameter value may be changed from the testbench to much lower values, suitable for verification (otherwise the simulation will run for hours to count 50 million pulses!).&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; output, &amp;#039;&amp;#039;&amp;#039;pulse&amp;#039;&amp;#039;&amp;#039;, is used to enable the counting of the &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039; counter.&lt;br /&gt;
&lt;br /&gt;
=== cnt_bcd ===&lt;br /&gt;
&lt;br /&gt;
Whenever its &amp;#039;&amp;#039;&amp;#039;cen&amp;#039;&amp;#039;&amp;#039; input is active, it increments or decrements, according to &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; input. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; it increments. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; it decrements.&lt;br /&gt;
&lt;br /&gt;
=== fsm_cnt ===&lt;br /&gt;
&lt;br /&gt;
This automaton controls the sequence generated by &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039;, changing its direction of counting such that to keep the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence between the limits, &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;. Whenever &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value reaches one of the limits, the counting direction, &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039;, is reversed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fsm_ctrl ===&lt;br /&gt;
&lt;br /&gt;
Another automaton controls the configuration process. It keeps two registers, &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039;, whose values are changed according to the configuration protocol described above. At the reset, their values are set to the default ones, &amp;#039;&amp;#039;&amp;#039;9&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Two successive push update the values of the limits, after which the new limit values stay stable until reset. A push is completed after the button is released.&lt;br /&gt;
&lt;br /&gt;
=== rom16x8 ===&lt;br /&gt;
&lt;br /&gt;
The ROM memory is a dual port read only memory. It may be initialized through the &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; tasks with proper values for digit display. Alternatively, the initialization of the memory content may be done with an &amp;#039;&amp;#039;&amp;#039;init&amp;#039;&amp;#039;&amp;#039; process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin // the last 7 bits are the digit segment values&lt;br /&gt;
    mem[0] = 8&amp;#039;b01000000;&lt;br /&gt;
    mem[1] = 8&amp;#039;b01111001;&lt;br /&gt;
    .... // initialization for the other memory locations&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
Write a testbench with the following test scenario:&lt;br /&gt;
* apply reset&lt;br /&gt;
* wait for 100 clock cycles&lt;br /&gt;
* set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* change &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a high limit and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* let the simulation run for some other 100 clock cycles&lt;br /&gt;
&lt;br /&gt;
In the testbench module redefine the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; parameter, such that is generates a pulse at each 5 clock cycles (instead of one at each 50,000,000 cycles):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
defparam dut.pulsegen.CYCLE = 5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
Using the recommended board display digits, push buttons, switches and clock sources (see Figure 1), implement the &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039; top-level design module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
pulsegen(rst, clk, pulse) with an internal parameter named &amp;#039;&amp;#039;&amp;#039;CYCLE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
cnt_bcd(rst, clk, cen, dir, value)&lt;br /&gt;
&lt;br /&gt;
fsm_cnt(rst, clk, limith, limitl, value, dir)&lt;br /&gt;
&lt;br /&gt;
fsm_ctrl(rst, clk, push, din, limith, limitl)&lt;br /&gt;
&lt;br /&gt;
rom16x8(addra, douta, addrb, doutb)&lt;br /&gt;
&lt;br /&gt;
triangle(rst, clk, push, din, seg_din, seg_bcd) with the pulsegen instance name &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; and a 4 bit connection named &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
triangle_tb with the triangle instance name &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8077</id>
		<title>Applications 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8077"/>
		<updated>2025-05-04T21:17:55Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* pulsegen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirement ==&lt;br /&gt;
&amp;#039;&amp;#039;Design, verify and implement a triangular sequence generator. It generates a sequence of numbers that periodically increase and decrease between two configurable limits, limith and limitl. The sequence rate is one number per second. The binary sequence of numbers, &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;, is outputted for display as &amp;#039;&amp;#039;&amp;#039;seg_bcd&amp;#039;&amp;#039;&amp;#039;. Figure 1 shows an example of triangular sequence that varies between 6 and 9. The bottom waveform is the analog signal that would be generated by a DAC whose input is the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle_wave.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;The default limit values are 0 for &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and 9 for &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;, and they are set each time the reset is applied. To change the limits use the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button in this order. Set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a desired value for the low limit and push the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button to set the &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; value to &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. Then change the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value to the desired high limit and with a second push set the &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; value this new &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. The current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value is displayed through &amp;#039;&amp;#039;&amp;#039;seg_din&amp;#039;&amp;#039;&amp;#039; output. After configuration is done, the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button is ignored.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== triangle ===&lt;br /&gt;
&lt;br /&gt;
The top level design, named &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039;, has 4 sequential blocks and one dual port ROM memory (Figure 2).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle.png]]&lt;br /&gt;
&lt;br /&gt;
All sequential blocks are clocked by the same 100 MHz input clock and share the reset sinal, &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, active &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== pulsegen ===&lt;br /&gt;
&lt;br /&gt;
To easy the design of the circuit, the pulse generator, &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039;, generates a periodic sequence of pulses, at a rate of one pulse per second, each pulse lasting only one clock cycle. The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; is a counter that generates one pulse at each 10 million clock cycles. However, to make possible the verification of the circuit, this number is not given as an explicit literal in HDL description but as a parameter declared inside the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
parameter CYCLE = 100_000_000;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameter value may be changed from the testbench to much lower values, suitable for verification (otherwise the simulation will run for hours to count 50 million pulses!).&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; output, &amp;#039;&amp;#039;&amp;#039;pulse&amp;#039;&amp;#039;&amp;#039;, is used to enable the counting of the &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039; counter.&lt;br /&gt;
&lt;br /&gt;
=== cnt_bcd ===&lt;br /&gt;
&lt;br /&gt;
Whenever its &amp;#039;&amp;#039;&amp;#039;cen&amp;#039;&amp;#039;&amp;#039; input is active, it increments or decrements, according to &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; input. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; it increments. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; it decrements.&lt;br /&gt;
&lt;br /&gt;
=== fsm_cnt ===&lt;br /&gt;
&lt;br /&gt;
This automaton controls the sequence generated by &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039;, changing its direction of counting such that to keep the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence between the limits, &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;. Whenever &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value reaches one of the limits, the counting direction, &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039;, is reversed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fsm_ctrl ===&lt;br /&gt;
&lt;br /&gt;
Another automaton controls the configuration process. It keeps two registers, &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039;, whose values are changed according to the configuration protocol described above. At the reset, their values are set to the default ones, &amp;#039;&amp;#039;&amp;#039;9&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Two successive push update the values of the limits, after which the new limit values stay stable until reset. Keep in mind that the push button is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;, and that a push is completed after the button is released.&lt;br /&gt;
&lt;br /&gt;
=== rom16x8 ===&lt;br /&gt;
&lt;br /&gt;
The ROM memory is a dual port read only memory. It may be initialized through the &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; tasks with proper values for digit display. Alternatively, the initialization of the memory content may be done with an &amp;#039;&amp;#039;&amp;#039;init&amp;#039;&amp;#039;&amp;#039; process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin // the last 7 bits are the digit segment values&lt;br /&gt;
    mem[0] = 8&amp;#039;b01000000;&lt;br /&gt;
    mem[1] = 8&amp;#039;b01111001;&lt;br /&gt;
    .... // initialization for the other memory locations&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
Write a testbench with the following test scenario:&lt;br /&gt;
* apply reset&lt;br /&gt;
* wait for 100 clock cycles&lt;br /&gt;
* set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* change &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a high limit and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* let the simulation run for some other 100 clock cycles&lt;br /&gt;
&lt;br /&gt;
In the testbench module redefine the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; parameter, such that is generates a pulse at each 5 clock cycles (instead of one at each 50,000,000 cycles):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
defparam dut.pulsegen.CYCLE = 5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
Using the recommended board display digits, push buttons, switches and clock sources (see Figure 1), implement the &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039; top-level design module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
pulsegen(rst, clk, pulse) with an internal parameter named &amp;#039;&amp;#039;&amp;#039;CYCLE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
cnt_bcd(rst, clk, cen, dir, value)&lt;br /&gt;
&lt;br /&gt;
fsm_cnt(rst, clk, limith, limitl, value, dir)&lt;br /&gt;
&lt;br /&gt;
fsm_ctrl(rst, clk, push, din, limith, limitl)&lt;br /&gt;
&lt;br /&gt;
rom16x8(addra, douta, addrb, doutb)&lt;br /&gt;
&lt;br /&gt;
triangle(rst, clk, push, din, seg_din, seg_bcd) with the pulsegen instance name &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; and a 4 bit connection named &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
triangle_tb with the triangle instance name &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8076</id>
		<title>Applications 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_10&amp;diff=8076"/>
		<updated>2025-05-04T21:17:02Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* triangle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Requirement ==&lt;br /&gt;
&amp;#039;&amp;#039;Design, verify and implement a triangular sequence generator. It generates a sequence of numbers that periodically increase and decrease between two configurable limits, limith and limitl. The sequence rate is one number per second. The binary sequence of numbers, &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;, is outputted for display as &amp;#039;&amp;#039;&amp;#039;seg_bcd&amp;#039;&amp;#039;&amp;#039;. Figure 1 shows an example of triangular sequence that varies between 6 and 9. The bottom waveform is the analog signal that would be generated by a DAC whose input is the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle_wave.png|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;The default limit values are 0 for &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and 9 for &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;, and they are set each time the reset is applied. To change the limits use the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button in this order. Set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a desired value for the low limit and push the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button to set the &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; value to &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. Then change the &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value to the desired high limit and with a second push set the &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; value this new &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value. The current &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; value is displayed through &amp;#039;&amp;#039;&amp;#039;seg_din&amp;#039;&amp;#039;&amp;#039; output. After configuration is done, the &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; button is ignored.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== triangle ===&lt;br /&gt;
&lt;br /&gt;
The top level design, named &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039;, has 4 sequential blocks and one dual port ROM memory (Figure 2).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl10_triangle.png]]&lt;br /&gt;
&lt;br /&gt;
All sequential blocks are clocked by the same 100 MHz input clock and share the reset sinal, &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, active &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== pulsegen ===&lt;br /&gt;
&lt;br /&gt;
To easy the design of the circuit, the pulse generator, &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039;, generates a periodic sequence of pulses, at a rate of one pulse per second, each pulse lasting only one clock cycle. The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; is a counter that generates one pulse at each 50,000,000 clock cycles. However, to make possible the verification of the circuit, this number is not given as an explicit literal in HDL description but as a parameter declared inside the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; module:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
parameter CYCLE = 50000000;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The parameter value may be changed from the testbench to much lower values, suitable for verification (otherwise the simulation will run for hours to count 50 million pulses!).&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; output, &amp;#039;&amp;#039;&amp;#039;pulse&amp;#039;&amp;#039;&amp;#039;, is used to enable the counting of the &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039; counter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== cnt_bcd ===&lt;br /&gt;
&lt;br /&gt;
Whenever its &amp;#039;&amp;#039;&amp;#039;cen&amp;#039;&amp;#039;&amp;#039; input is active, it increments or decrements, according to &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; input. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; it increments. If &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039; is &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; it decrements.&lt;br /&gt;
&lt;br /&gt;
=== fsm_cnt ===&lt;br /&gt;
&lt;br /&gt;
This automaton controls the sequence generated by &amp;#039;&amp;#039;&amp;#039;cnt_bcd&amp;#039;&amp;#039;&amp;#039;, changing its direction of counting such that to keep the &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; sequence between the limits, &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039;. Whenever &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039; value reaches one of the limits, the counting direction, &amp;#039;&amp;#039;&amp;#039;dir&amp;#039;&amp;#039;&amp;#039;, is reversed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fsm_ctrl ===&lt;br /&gt;
&lt;br /&gt;
Another automaton controls the configuration process. It keeps two registers, &amp;#039;&amp;#039;&amp;#039;limith&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;limitl&amp;#039;&amp;#039;&amp;#039;, whose values are changed according to the configuration protocol described above. At the reset, their values are set to the default ones, &amp;#039;&amp;#039;&amp;#039;9&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Two successive push update the values of the limits, after which the new limit values stay stable until reset. Keep in mind that the push button is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;, and that a push is completed after the button is released.&lt;br /&gt;
&lt;br /&gt;
=== rom16x8 ===&lt;br /&gt;
&lt;br /&gt;
The ROM memory is a dual port read only memory. It may be initialized through the &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; tasks with proper values for digit display. Alternatively, the initialization of the memory content may be done with an &amp;#039;&amp;#039;&amp;#039;init&amp;#039;&amp;#039;&amp;#039; process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial begin // the last 7 bits are the digit segment values&lt;br /&gt;
    mem[0] = 8&amp;#039;b01000000;&lt;br /&gt;
    mem[1] = 8&amp;#039;b01111001;&lt;br /&gt;
    .... // initialization for the other memory locations&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
Write a testbench with the following test scenario:&lt;br /&gt;
* apply reset&lt;br /&gt;
* wait for 100 clock cycles&lt;br /&gt;
* set &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* change &amp;#039;&amp;#039;&amp;#039;din&amp;#039;&amp;#039;&amp;#039; to a high limit and apply &amp;#039;&amp;#039;&amp;#039;push&amp;#039;&amp;#039;&amp;#039; for a couple of cycles&lt;br /&gt;
* let the simulation run for some other 100 clock cycles&lt;br /&gt;
&lt;br /&gt;
In the testbench module redefine the &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; parameter, such that is generates a pulse at each 5 clock cycles (instead of one at each 50,000,000 cycles):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
defparam dut.pulsegen.CYCLE = 5;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
Using the recommended board display digits, push buttons, switches and clock sources (see Figure 1), implement the &amp;#039;&amp;#039;&amp;#039;triangle&amp;#039;&amp;#039;&amp;#039; top-level design module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
&lt;br /&gt;
pulsegen(rst, clk, pulse) with an internal parameter named &amp;#039;&amp;#039;&amp;#039;CYCLE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
cnt_bcd(rst, clk, cen, dir, value)&lt;br /&gt;
&lt;br /&gt;
fsm_cnt(rst, clk, limith, limitl, value, dir)&lt;br /&gt;
&lt;br /&gt;
fsm_ctrl(rst, clk, push, din, limith, limitl)&lt;br /&gt;
&lt;br /&gt;
rom16x8(addra, douta, addrb, doutb)&lt;br /&gt;
&lt;br /&gt;
triangle(rst, clk, push, din, seg_din, seg_bcd) with the pulsegen instance name &amp;#039;&amp;#039;&amp;#039;pulsegen&amp;#039;&amp;#039;&amp;#039; and a 4 bit connection named &amp;#039;&amp;#039;&amp;#039;bcd&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
triangle_tb with the triangle instance name &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8075</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8075"/>
		<updated>2025-04-29T23:35:42Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* State transitions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal signal declarations&lt;br /&gt;
# description (structural with instantiations, or behavioral with always processes and continuous assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process is sensitive only to the active clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The state variable must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always_comb&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always_comb&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8074</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8074"/>
		<updated>2025-04-29T23:32:32Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Outputs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal signal declarations&lt;br /&gt;
# description (structural with instantiations, or behavioral with always processes and continuous assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process is sensitive only to the active clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always_comb&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always_comb&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8073</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8073"/>
		<updated>2025-04-29T23:31:50Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Outputs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal signal declarations&lt;br /&gt;
# description (structural with instantiations, or behavioral with always processes and continuous assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process is sensitive only to the active clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always_comb&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always_comb&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
The outputs must be declared of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8072</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8072"/>
		<updated>2025-04-29T23:30:58Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* State coding */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal signal declarations&lt;br /&gt;
# description (structural with instantiations, or behavioral with always processes and continuous assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process is sensitive only to the active clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always_comb&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
The outputs must be declared of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Appl9_moore_wave.png&amp;diff=8071</id>
		<title>Fișier:Appl9 moore wave.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Appl9_moore_wave.png&amp;diff=8071"/>
		<updated>2025-04-29T23:11:18Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: Zhascsi a încărcat o versiune nouă pentru Fișier:Appl9 moore wave.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8070</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8070"/>
		<updated>2025-04-29T23:08:43Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Outputs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (the list of inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal wire and reg declarations&lt;br /&gt;
# description (structural with instantiations or behavioral with always processes and continuos assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process is sensitive only to the active clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always_comb&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
The outputs must be declared of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8069</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8069"/>
		<updated>2025-04-29T23:08:08Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* State transitions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (the list of inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal wire and reg declarations&lt;br /&gt;
# description (structural with instantiations or behavioral with always processes and continuos assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process is sensitive only to the active clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
The outputs must be declared of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8068</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8068"/>
		<updated>2025-04-29T23:07:09Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Exercise 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (the list of inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal wire and reg declarations&lt;br /&gt;
# description (structural with instantiations or behavioral with always processes and continuos assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is sensitive only to clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always_ff&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
The outputs must be declared of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8067</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8067"/>
		<updated>2025-04-29T23:06:23Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Exercise 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (the list of inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal wire and reg declarations&lt;br /&gt;
# description (structural with instantiations or behavioral with always processes and continuos assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is sensitive only to clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE. The reset is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
The outputs must be declared of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Appl9_ex1.png&amp;diff=8066</id>
		<title>Fișier:Appl9 ex1.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Appl9_ex1.png&amp;diff=8066"/>
		<updated>2025-04-29T23:03:40Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: Zhascsi a încărcat o versiune nouă pentru Fișier:Appl9 ex1.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8065</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8065"/>
		<updated>2025-04-29T23:00:14Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* State transitions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset. The reset is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (the list of inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal wire and reg declarations&lt;br /&gt;
# description (structural with instantiations or behavioral with always processes and continuos assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is sensitive only to clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
&amp;lt;!--* To implement the design assign KEY0, SW1 and SW2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LEDR1 and LEDR2 to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.--&amp;gt;&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE. The reset is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
The outputs must be declared of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8064</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8064"/>
		<updated>2025-04-29T22:59:04Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Outputs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset. The reset is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (the list of inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal wire and reg declarations&lt;br /&gt;
# description (structural with instantiations or behavioral with always processes and continuos assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is sensitive only to clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_comb begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
&amp;lt;!--* To implement the design assign KEY0, SW1 and SW2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LEDR1 and LEDR2 to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.--&amp;gt;&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE. The reset is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
The outputs must be declared of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8063</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8063"/>
		<updated>2025-04-29T22:58:17Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Outputs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset. The reset is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (the list of inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal wire and reg declarations&lt;br /&gt;
# description (structural with instantiations or behavioral with always processes and continuos assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is sensitive only to clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(*) begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
&amp;lt;!--* To implement the design assign KEY0, SW1 and SW2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LEDR1 and LEDR2 to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.--&amp;gt;&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE. The reset is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
The outputs must be declared of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always_ff @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8062</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8062"/>
		<updated>2025-04-29T22:57:49Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Exercise 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset. The reset is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (the list of inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal wire and reg declarations&lt;br /&gt;
# description (structural with instantiations or behavioral with always processes and continuos assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is sensitive only to clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(*) begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
&amp;lt;!--* To implement the design assign KEY0, SW1 and SW2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LEDR1 and LEDR2 to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.--&amp;gt;&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE. The reset is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
The outputs must be declared of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always_ff @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8061</id>
		<title>Applications 9</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_9&amp;diff=8061"/>
		<updated>2025-04-29T22:57:29Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Exercise 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Almost always the FSM is described behaviorally, leaving the CLC gate level generation and optimization to compiler/synthesizer. However, the usual behavioral description closely follows the block structure of the FSM, with one block that computes the transition function and another block that computes the output. The FSMs are of two categories:&lt;br /&gt;
* Moore FSM, whose outputs depend only on the current state&lt;br /&gt;
* Mealy FSM, whose outputs depend also on inputs&lt;br /&gt;
&lt;br /&gt;
Most often the Mealy FSM is a delayed Mealy FSM. Its output depends on the previous state and on the input values at transition time. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs remain asserted until reset. The reset is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
=== Moore FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a Moore FSM, with two separate states for those two particular output configurations. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final states, &amp;#039;&amp;#039;&amp;#039;R&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;U&amp;#039;&amp;#039;&amp;#039;, the automaton stays until reset. From any state the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== State coding ===&lt;br /&gt;
&lt;br /&gt;
It is not recommended to use explicit values whenever the state variable is used. To make code much more readable and easier to design and debug, the state values are parameters. Another advantage of using parameters is that the state explicit values are declared in a single place, at parameter declaration, therefore if their values need to be changed, only the parameter declaration is affected.&lt;br /&gt;
&lt;br /&gt;
The state values are internal design options, therefore the parameters used for states are local ones. They are declared as local parameters, using the template &amp;#039;&amp;#039;&amp;#039;localparam&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;name&amp;#039;&amp;#039;=&amp;#039;&amp;#039;value&amp;#039;&amp;#039;; The names of parameters are upper case letters, and may include digits and underline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
localparam STATE_S = 3&amp;#039;d0;&lt;br /&gt;
localparam STATE_P = 3&amp;#039;d1;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* The state values must be distinct! Otherwise you may end with a state having multiple names.&lt;br /&gt;
* Local parameter declarations are the first statements after the module interface. The order of statements for a module should be the following:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;module&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# interface declaration (the list of inputs and outputs)&lt;br /&gt;
# localparam declarations&lt;br /&gt;
# internal wire and reg declarations&lt;br /&gt;
# description (structural with instantiations or behavioral with always processes and continuos assignments)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;endmodule&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
All transitions are grouped in a single sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process, with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that groups transitions by current state.&lt;br /&gt;
The combinational function that computes the next state (the transition function) is implicitly described by the case statement and the statements for each case.&lt;br /&gt;
The state is updated sequentially because the &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is sensitive only to clock edges.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(~rst)&lt;br /&gt;
        state &amp;lt;= STATE_S;&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
            if(a)&lt;br /&gt;
                state &amp;lt;= STATE_P;&lt;br /&gt;
            else if(b)&lt;br /&gt;
                state &amp;lt;= STATE_T;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state; // stays in the same state&lt;br /&gt;
        end&lt;br /&gt;
        STATE_P: begin&lt;br /&gt;
            if(b)&lt;br /&gt;
                state &amp;lt;= STATE_R;&lt;br /&gt;
            else&lt;br /&gt;
                state &amp;lt;= state;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their transitions&lt;br /&gt;
        default:&lt;br /&gt;
                state &amp;lt;= STATE_S; // from undefined states jump to the initial state&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variable for the state must be declared with the required number of bits, which is the same as the number of bits declared for each value of the state value parameters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since Moore outputs depend only on state they are described either through continuous assignments, or inside a combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
&lt;br /&gt;
If continuous assignments are used, the outputs are assigned logic expressions based on state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign y1 = (state == R);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The combinational &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process is preferred when state values are easier to group by states:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(*) begin&lt;br /&gt;
    case(state)&lt;br /&gt;
    STATE_S: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_P: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    STATE_R: {y1, y2} = 2&amp;#039;b10;&lt;br /&gt;
    // other states with their outputs&lt;br /&gt;
    default: {y1, y2} = 2&amp;#039;b00;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the combinational process are done with the blocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Create a new project in a new folder&lt;br /&gt;
* Design the automaton as the top level design entity&lt;br /&gt;
* Design a testbench with the input signals generated as in the figure below.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure.&lt;br /&gt;
&amp;lt;!--* To implement the design assign KEY0, SW1 and SW2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LEDR1 and LEDR2 to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.--&amp;gt;&lt;br /&gt;
* To implement the design assign BTN0, BTN1 and BTN2 to &amp;#039;&amp;#039;&amp;#039;rst&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;, and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; inputs. Assign LED1 and LED2  to &amp;#039;&amp;#039;&amp;#039;y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;y2&amp;#039;&amp;#039;&amp;#039; outputs.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_moore_wave.png]]&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an automaton that determines the order in which two buttons are pressed. The buttons generate logic signals, &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;, that are &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; if the corresponding button is pressed. The automaton has two logic outputs, &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y1&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;Y2&amp;#039;&amp;#039;&amp;#039; is asserted if &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; was pressed first, followed by &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039;. The outputs are asserted for ONLY ONE CLOCK CYCLE. The reset is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mealy FSM ===&lt;br /&gt;
&lt;br /&gt;
The circuit may be designed as a delayed Mealy FSM, with fewer states than if designed as a Moore FSM. In the graph below only the transitions to different states are shown. If their conditions are not met, the FSM stays in the current state, whatever it is. In the final state, &amp;#039;&amp;#039;&amp;#039;V&amp;#039;&amp;#039;&amp;#039;, the outputs are active for one clock cycle, depending on the input values that determined the transition to it. All other transitions are with outputs &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. From any state, the reset forces the FSM to its initial state, &amp;#039;&amp;#039;&amp;#039;S&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy.png]]&lt;br /&gt;
&lt;br /&gt;
=== State transitions ===&lt;br /&gt;
&lt;br /&gt;
The transition function is described in the same way as for the Moore FSM. However, there are only 4 states, therefore the &amp;#039;&amp;#039;&amp;#039;state&amp;#039;&amp;#039;&amp;#039; variable and the state value parameters have only 2 bits. The &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; inside the sequential process for transitions has also fewer cases.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Outputs ===&lt;br /&gt;
&lt;br /&gt;
Since the delayed Mealy outputs depend both on the previous state AND the previous input values (at the last transition) they are described inside a sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process.&lt;br /&gt;
The outputs must be declared of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;verilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(~rst) begin&lt;br /&gt;
        y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
    end&lt;br /&gt;
    else begin&lt;br /&gt;
        case(state)&lt;br /&gt;
        STATE_S: begin&lt;br /&gt;
             y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
             y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        // other states with their outputs&lt;br /&gt;
        default: begin&lt;br /&gt;
            y1 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
            y2 &amp;lt;= 1&amp;#039;b0;&lt;br /&gt;
        end&lt;br /&gt;
        endcase&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* All assignments inside the sequential process are done with the nonblocking assignment operator, &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;lt;=&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t forget the &amp;#039;&amp;#039;&amp;#039;default&amp;#039;&amp;#039;&amp;#039; case!&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
* Use the same project as before&lt;br /&gt;
* Redesign the automaton as a Mealy FSM&lt;br /&gt;
* The testbench should not be modified.&lt;br /&gt;
* Run simulation. If the design is correct the outputs should appear as in the figure below. The differences from the previous waveform are in the state values and output pulses.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_mealy_wave.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Design an FSM for an automatic chocolate selling machine, which delivers chocolates at 2.5&amp;amp;#8364;. The machine accepts only coins of 50 cents and 1 euro, and does not return any change. When the amount of 2.5&amp;amp;#8364; or more is reached, the machine delivers a chocolate and will resume the process, subtracting 2.5&amp;amp;#8364; from the current amount. The process resumes with whatever amount remains after delivering, which may be 0 or 0.5&amp;amp;#8364;. &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The inputs are the digital signals &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When the user inserts a valid coin, the corresponding input, &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039;, is asserted and stays &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; for some clock cycles. The FSM considers the coin validated only after the corresponding input goes back to &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
The output is a digital signal, &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039;, that is asserted when the amount reaches or surpasses 2.5&amp;amp;#8364; and stays asserted until the input &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is asserted. The FSM resumes the process after &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; is deasserted.&lt;br /&gt;
&lt;br /&gt;
The internal states of the FSM may be equivalent to the current amount, 0, 0.5, 1, 1.5, 2, 2.5 and 3 euros.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Implement the FSM for the automatic chocolate selling machine using three push buttons for &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039; inputs &amp;lt;!--(the pushbutton generates &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; when pressed)--&amp;gt;, an LED to indicate the &amp;#039;&amp;#039;&amp;#039;deliver&amp;#039;&amp;#039;&amp;#039; output, and another pushbutton for the reset (that resets the amount to 0).&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hint&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
To easy the implementation and keep the FSM as simple as possible, the inputs &amp;#039;&amp;#039;&amp;#039;cents&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;ack&amp;#039;&amp;#039;&amp;#039;, which are pulses of arbitrary length (that may last hundreds of thousands of clock cycles!), may be transformed to one cycle pulses, asserted during the clock cycle that follows the original pulse. The FSM uses these one clock cycle pulses to compute the transitions.&lt;br /&gt;
&lt;br /&gt;
As an example, the &amp;#039;&amp;#039;&amp;#039;euro&amp;#039;&amp;#039;&amp;#039; input is transformed to &amp;#039;&amp;#039;&amp;#039;euro_p&amp;#039;&amp;#039;&amp;#039; internal signal,  whose pulses last one clock cycle. These internal signal is further used by the FSM.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
logic euro_d; // delayed version of the euro input&lt;br /&gt;
logic euro_p; // one clock cycle pulse to be used by the FSM&lt;br /&gt;
...&lt;br /&gt;
always @(posedge clk) euro_d &amp;lt;= euro; // euro_d is the copy of euro input, shifted one clock cycle&lt;br /&gt;
assign euro_p = euro_d &amp;amp; ~euro; // euro_p is asserted one clock cycle after euro pulse has ended&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl9_ex3wave.png]]&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Appl9_mealy_wave.png&amp;diff=8060</id>
		<title>Fișier:Appl9 mealy wave.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Appl9_mealy_wave.png&amp;diff=8060"/>
		<updated>2025-04-29T22:54:13Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: Zhascsi a încărcat o versiune nouă pentru Fișier:Appl9 mealy wave.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Digital_Integrated_Circuits_(lab)&amp;diff=8059</id>
		<title>Digital Integrated Circuits (lab)</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Digital_Integrated_Circuits_(lab)&amp;diff=8059"/>
		<updated>2025-04-29T22:46:10Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# [[Applications 1 | Laboratory 1]]&lt;br /&gt;
# [[Applications 2 | Laboratory 2]]&lt;br /&gt;
# [[Applications 3 | Laboratory 3]]&lt;br /&gt;
# [[Applications 4 | Laboratory 4]]&lt;br /&gt;
# [[Applications 5 | Laboratory 5]]&lt;br /&gt;
# Test 1&lt;br /&gt;
# [[Applications 6 | Laboratory 6]]&lt;br /&gt;
# [[Applications 7 | Laboratory 7]]&lt;br /&gt;
# [[Applications 8 | Laboratory 8]]&lt;br /&gt;
# [[Applications 9 | Laboratory 9]]&lt;br /&gt;
&lt;br /&gt;
== Verilog Tutorials ==&lt;br /&gt;
* [http://www.asic-world.com/verilog/veritut.html Verilog Tutorial] from ASIC World&lt;br /&gt;
* [http://chipverify.com/verilog/verilog-tutorial Verilog Tutorial] from Chip Verify&lt;br /&gt;
* [http://www.emmelmann.org/Library/Tutorials/docs/verilog_ref_guide/vlog_ref_top.html Verilog reference guide]&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
* [https://www.xilinx.com/products/design-tools/vivado/vivado-ml.html Vivado™ ML Standard Edition free]&lt;br /&gt;
* [https://wiki.dcae.pub.ro/images/2/24/VivadoNewProjectTutorial.pdf Vivado New Project Tutorial]&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
[https://www.realdigital.org/hardware/boolean Boolean Board] from RealDigital&lt;br /&gt;
* [https://www.realdigital.org/doc/02013cd17602c8af749f00561f88ae21 Boolean Board - user manual]&lt;br /&gt;
* [[Boolean Board - Pinout]]&lt;br /&gt;
To implement a circuit on Boolean Board you should select the following target device in Project Settings: &amp;#039;&amp;#039;&amp;#039;xc7s50csga324-1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
* [https://dpoauwgwqsy2x.cloudfront.net/Download/pynqz2_user_manual_v1_0.pdf Pynq-Z2 - user manual]&lt;br /&gt;
* [[Pynq-Z2 - Pinout]]&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Zlab8_ram.png&amp;diff=8058</id>
		<title>Fișier:Zlab8 ram.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Zlab8_ram.png&amp;diff=8058"/>
		<updated>2025-04-21T22:02:23Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: Zhascsi a readus Fișier:Zlab8 ram.png la o versiune mai veche&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Zlab8_ram.png&amp;diff=8057</id>
		<title>Fișier:Zlab8 ram.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Zlab8_ram.png&amp;diff=8057"/>
		<updated>2025-04-21T22:00:50Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: Zhascsi a readus Fișier:Zlab8 ram.png la o versiune mai veche&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Zlab8_ram.png&amp;diff=8056</id>
		<title>Fișier:Zlab8 ram.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Zlab8_ram.png&amp;diff=8056"/>
		<updated>2025-04-21T22:00:13Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: Zhascsi a încărcat o versiune nouă pentru Fișier:Zlab8 ram.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Appl8_ram.png&amp;diff=8055</id>
		<title>Fișier:Appl8 ram.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Appl8_ram.png&amp;diff=8055"/>
		<updated>2025-04-21T21:59:17Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: Zhascsi a readus Fișier:Appl8 ram.png la o versiune mai veche&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Appl8_ram.png&amp;diff=8054</id>
		<title>Fișier:Appl8 ram.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Appl8_ram.png&amp;diff=8054"/>
		<updated>2025-04-21T21:59:08Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: Zhascsi a încărcat o versiune nouă pentru Fișier:Appl8 ram.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_8&amp;diff=8053</id>
		<title>Applications 8</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_8&amp;diff=8053"/>
		<updated>2025-04-21T21:56:52Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* RAM - Read-Write Memory */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A random access memory is an address-based data storage block, with a highly regular structure, which may be logically defined either as a bi-dimensional array of bits, or a uni-dimensional list of data words. Each row of the array, or each item of the list has a unique address. The addresses form a contiguous set of integers, starting from zero and running up to the highest address which defines the size of the address space, usually a power of 2. The memory capacity is therefore the number of address locations, N, times the width of the memory location (or of the memory word), W. These two numbers are the main parameters of any memory:&lt;br /&gt;
* N - the number of address locations, also the number of words;&lt;br /&gt;
* W - the number of bits for each location, or the data word width;&lt;br /&gt;
The storage capacity is N x W bits, but the memory capacity may also be given in bytes.&lt;br /&gt;
&lt;br /&gt;
Being a vector of words or a bidimensional array of bits, the memory could be described using a single bidimensional variable, usually declared as a vector of multibit &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; items. A memory array of N locations, with W bits per location is declared as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
logic [W-1:0] memory [0:N-1];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* the width of the word is declared as usual, with msb as the left index, &amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot; inline&amp;gt;[msb:0]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* the length of the memory is declared after the variable name, and starts with 0, the right index being the highest index of the vector, &amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot; inline&amp;gt;[0:endindex]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are two kinds of memories:&lt;br /&gt;
* read-only memories&lt;br /&gt;
* writable memories&lt;br /&gt;
&lt;br /&gt;
Memories can also be classified by their synchronous or asynchronous character:&lt;br /&gt;
* asynchronous - read data is immediately available at the output, write is performed as into a latch&lt;br /&gt;
* synchronous  - all operations are synchronized by one of the clock edges.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
=== ROM - Read-Only Memory ===&lt;br /&gt;
&lt;br /&gt;
It may be described as a purely combinational logic circuit, whose output (data) is a logic function of its input (address). The transcoder from [[Applications 4#transcoder|Applications 4]] is nothing else than a ROM, with &amp;#039;&amp;#039;&amp;#039;value&amp;#039;&amp;#039;&amp;#039; input acting as an address that selects a particular location from where data is read and sent out as &amp;#039;&amp;#039;&amp;#039;seg&amp;#039;&amp;#039;&amp;#039;. There it was described behaviorally with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that had a branch for each combination of input value bits.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_rom.png]]&lt;br /&gt;
&lt;br /&gt;
A more flexible description employs a single memory array, declared as a vector of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variables, and a statement that assigns the selected (addressed) element of the memory vector to the memory output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign dout = memory[addr];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Memory initialization task ===&lt;br /&gt;
&lt;br /&gt;
Memory arrays may be initialized with predefined values from a text file using verilog system tasks &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; reads predefined values given in binary, while &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; is used if values are given in hexadecimal. These verilog system tasks have two mandatory arguments and two optional arguments, in the following order:&lt;br /&gt;
# initialization filename, given as a string (between double quotes)&lt;br /&gt;
# the memory array variable name&lt;br /&gt;
# the start address (optional)&lt;br /&gt;
# the end address  (optional)&lt;br /&gt;
If the start and end addresses are not given, the memory array is initialized from the first address (address zero) until the last address or until the end of initialization file is reached.&lt;br /&gt;
&lt;br /&gt;
If the memory initialization file, &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039;, resides in the project&amp;#039;s folder, and the memory array to be initialized is &amp;#039;&amp;#039;&amp;#039;mem&amp;#039;&amp;#039;&amp;#039; inside the memory instance &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;, the testbench may initialize the memory right at the beginning of the simulation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial $readmemb(&amp;quot;../../meminit.txt&amp;quot;, dut.mem);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the initialization is intended to be done for the implemented memory, the initialization process must be placed inside the memory module, in which case the memory array name is just the variable array to be initialized:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial $readmemb(&amp;quot;../../meminit.txt&amp;quot;, mem);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The filename, the first argument of &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; tasks, may be given either relative to the simulation folder (as in the previous two examples), or as the complete absolute filename, with the pathname starting from the linux root, &amp;#039;&amp;#039;&amp;#039;/&amp;#039;&amp;#039;&amp;#039;, for example &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;quot;/home/student/rom/meminit.txt&amp;quot;&amp;lt;/syntaxhighlight&amp;gt; if &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039; file resides in the project&amp;#039;s folder &amp;#039;&amp;#039;rom&amp;#039;&amp;#039;, created in the student&amp;#039;s home directory &amp;#039;&amp;#039;/home/student&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== Memory initialization file ===&lt;br /&gt;
&lt;br /&gt;
The initialization file is a text file with values written in binary (using &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; symbols) or in hexadecimal (using digits and letters &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; to &amp;#039;&amp;#039;&amp;#039;f&amp;#039;&amp;#039;&amp;#039;, either uppercase of lowercase). Values are separated by white spaces, tabs or newlines. Comments (started with &amp;#039;&amp;#039;&amp;#039;//&amp;#039;&amp;#039;&amp;#039; as in verilog) are ignored. An example of a binary initialization file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
// four values in binary text format&lt;br /&gt;
00000011&lt;br /&gt;
00001111&lt;br /&gt;
00111111&lt;br /&gt;
11111111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same initialization sequence, but given as a hexadecimal text file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
// four values in hexadecimal text format&lt;br /&gt;
03&lt;br /&gt;
0f&lt;br /&gt;
3f&lt;br /&gt;
ff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039;, in a newly created folder &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Create a new verilog file &amp;#039;&amp;#039;rom.sv&amp;#039;&amp;#039; that describes a 16x8 ROM using a vector variable and a continuous assignment.&lt;br /&gt;
* Create a testbench, &amp;#039;&amp;#039;&amp;#039;rom_tb&amp;#039;&amp;#039;&amp;#039;, that drives the input of &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039; with a sequence of addresses from 0 to highest one. Run simulation.&lt;br /&gt;
* Open a text editor, write some values in binary format on successive lines, and save the file into the &amp;#039;&amp;#039;rom&amp;#039;&amp;#039; folder with the name &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039;&lt;br /&gt;
* In the testbench module add an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process with a single statement that calls the system task for memory initialization. Run simulation.&lt;br /&gt;
* Assign the segments of a display to &amp;#039;&amp;#039;&amp;#039;dout&amp;#039;&amp;#039;&amp;#039;, and 4 switches, from SW3 to SW0, to &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
* In the &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039; module add an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process with a single statement that calls the system task for memory initialization. Pay atention how its second argument is given - the array variable is now directly accesible. Compile the project and program the FPGA.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
=== RAM - Read-Write Memory ===&lt;br /&gt;
&lt;br /&gt;
A synchronous memory reacts only on clock edges. The addresses are sampled at clock edges, the output changes also on clock edges, and the write is performed on clock edges too.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: Zlab8_ram.png]]&lt;br /&gt;
&lt;br /&gt;
The FPGA has dedicated blocks for memory implementation, the so called &amp;#039;&amp;#039;ram blocks&amp;#039;&amp;#039;, or &amp;#039;&amp;#039;ramblocks&amp;#039;&amp;#039;. In order for the synthesis to map a memory description to a &amp;#039;&amp;#039;ramblock&amp;#039;&amp;#039;, the sequential description must conform to a template:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(~we)                   // if write is enabled,&lt;br /&gt;
        mem[addr] &amp;lt;= wdata;   //     update the addressed location to wdata value&lt;br /&gt;
    rdata &amp;lt;= mem[addr];       // data read from the addressed location is transferred to the output&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039;, in a new folder &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Create a new verilog file &amp;#039;&amp;#039;ram.sv&amp;#039;&amp;#039; that describes a 16x4 RAM using a vector variable and a sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process that assigns to &amp;#039;&amp;#039;&amp;#039;rdata&amp;#039;&amp;#039;&amp;#039; output the value of the memory location selected by &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039;. In the same process update the same location with &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; value if &amp;#039;&amp;#039;&amp;#039;we&amp;#039;&amp;#039;&amp;#039; input is active (active at &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
* Create a testbench, &amp;#039;&amp;#039;&amp;#039;ram_tb&amp;#039;&amp;#039;&amp;#039;, which writes some data to four addresses, and then reads the same addresses in the same order, as indicated in the waveforms below. Don&amp;#039;t forget the clock! Run simulation and check that the written data are correctly read afterwards.&lt;br /&gt;
* Assign LEDs to the output, switches to the &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; inputs, a push button to the write enable input, and the board&amp;#039;s source clock to &amp;#039;&amp;#039;&amp;#039;clk&amp;#039;&amp;#039;&amp;#039; input.&lt;br /&gt;
* Compile, program the FPGA and test the RAM. Set switches to an address and a data value, then briefly push the write enable button. The LEDs will change accordingly. Change the address and data and push again the write enable button. Change back the address switches and see if the previously written configuration reappears on LED.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: Zlab8_ram_wave.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
=== Programmable display ===&lt;br /&gt;
&lt;br /&gt;
These application employs a dual port synchronous RAM. One port, the &amp;#039;&amp;#039;read port&amp;#039;&amp;#039;, is used to read data (&amp;#039;&amp;#039;&amp;#039;rdata&amp;#039;&amp;#039;&amp;#039;) from the memory, using the read address &amp;#039;&amp;#039;&amp;#039;raddr&amp;#039;&amp;#039;&amp;#039;. The other, the &amp;#039;&amp;#039;write port&amp;#039;&amp;#039;, accesses the same memory array, but using another address, &amp;#039;&amp;#039;&amp;#039;waddr&amp;#039;&amp;#039;&amp;#039;, to write &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; into. The write operation is performed only if the write enable pin (&amp;#039;&amp;#039;&amp;#039;we&amp;#039;&amp;#039;&amp;#039;) is active (here it is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
The data read from RAM is translated by the ROM into a 7 bit combination for the digit display. The RAM memory is read in sequence, address by address, changing the address at around each second. The sequence of 4 bit addresses are generated by a counter from which four suitable bits are chosen such that the rate of change is around 1 Hz.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_ramrom.png]]&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;ramrom&amp;#039;&amp;#039;&amp;#039;, in a newly created folder &amp;#039;&amp;#039;&amp;#039;ramrom&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* Copy the &amp;#039;&amp;#039;rom.v&amp;#039;&amp;#039; file from Exercise 1 into this folder.&lt;br /&gt;
* Add an initialization file to this folder, and ensures that &amp;#039;&amp;#039;rom.v&amp;#039;&amp;#039; initialization tasks reads it from the correct location.&lt;br /&gt;
* Copy the &amp;#039;&amp;#039;ram.v&amp;#039;&amp;#039; from from Exercise 2 into this folder. Change &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039; description to a dual RAM.&lt;br /&gt;
* Add &amp;#039;&amp;#039;&amp;#039;cnt32.v&amp;#039;&amp;#039;&amp;#039; to this project (you may reuse the &amp;#039;&amp;#039;&amp;#039;cnt32&amp;#039;&amp;#039;&amp;#039; module or file from the previous Application).&lt;br /&gt;
* Create the top-level design file, &amp;#039;&amp;#039;ramrom.v&amp;#039;&amp;#039;&amp;#039;, and instantiate the modules and connect them as indicated.&lt;br /&gt;
* Assign swithces, push button, clock source and digit display as shown.&lt;br /&gt;
* Compile, program the FPGA, and play with the board switches and buttons.&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Zlab8_ram_wave.png&amp;diff=8052</id>
		<title>Fișier:Zlab8 ram wave.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Zlab8_ram_wave.png&amp;diff=8052"/>
		<updated>2025-04-21T21:56:30Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_8&amp;diff=8051</id>
		<title>Applications 8</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_8&amp;diff=8051"/>
		<updated>2025-04-21T21:42:09Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* RAM - Read-Write Memory */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A random access memory is an address-based data storage block, with a highly regular structure, which may be logically defined either as a bi-dimensional array of bits, or a uni-dimensional list of data words. Each row of the array, or each item of the list has a unique address. The addresses form a contiguous set of integers, starting from zero and running up to the highest address which defines the size of the address space, usually a power of 2. The memory capacity is therefore the number of address locations, N, times the width of the memory location (or of the memory word), W. These two numbers are the main parameters of any memory:&lt;br /&gt;
* N - the number of address locations, also the number of words;&lt;br /&gt;
* W - the number of bits for each location, or the data word width;&lt;br /&gt;
The storage capacity is N x W bits, but the memory capacity may also be given in bytes.&lt;br /&gt;
&lt;br /&gt;
Being a vector of words or a bidimensional array of bits, the memory could be described using a single bidimensional variable, usually declared as a vector of multibit &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; items. A memory array of N locations, with W bits per location is declared as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
logic [W-1:0] memory [0:N-1];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* the width of the word is declared as usual, with msb as the left index, &amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot; inline&amp;gt;[msb:0]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* the length of the memory is declared after the variable name, and starts with 0, the right index being the highest index of the vector, &amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot; inline&amp;gt;[0:endindex]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are two kinds of memories:&lt;br /&gt;
* read-only memories&lt;br /&gt;
* writable memories&lt;br /&gt;
&lt;br /&gt;
Memories can also be classified by their synchronous or asynchronous character:&lt;br /&gt;
* asynchronous - read data is immediately available at the output, write is performed as into a latch&lt;br /&gt;
* synchronous  - all operations are synchronized by one of the clock edges.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
=== ROM - Read-Only Memory ===&lt;br /&gt;
&lt;br /&gt;
It may be described as a purely combinational logic circuit, whose output (data) is a logic function of its input (address). The transcoder from [[Applications 4#transcoder|Applications 4]] is nothing else than a ROM, with &amp;#039;&amp;#039;&amp;#039;value&amp;#039;&amp;#039;&amp;#039; input acting as an address that selects a particular location from where data is read and sent out as &amp;#039;&amp;#039;&amp;#039;seg&amp;#039;&amp;#039;&amp;#039;. There it was described behaviorally with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that had a branch for each combination of input value bits.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_rom.png]]&lt;br /&gt;
&lt;br /&gt;
A more flexible description employs a single memory array, declared as a vector of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variables, and a statement that assigns the selected (addressed) element of the memory vector to the memory output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign dout = memory[addr];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Memory initialization task ===&lt;br /&gt;
&lt;br /&gt;
Memory arrays may be initialized with predefined values from a text file using verilog system tasks &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; reads predefined values given in binary, while &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; is used if values are given in hexadecimal. These verilog system tasks have two mandatory arguments and two optional arguments, in the following order:&lt;br /&gt;
# initialization filename, given as a string (between double quotes)&lt;br /&gt;
# the memory array variable name&lt;br /&gt;
# the start address (optional)&lt;br /&gt;
# the end address  (optional)&lt;br /&gt;
If the start and end addresses are not given, the memory array is initialized from the first address (address zero) until the last address or until the end of initialization file is reached.&lt;br /&gt;
&lt;br /&gt;
If the memory initialization file, &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039;, resides in the project&amp;#039;s folder, and the memory array to be initialized is &amp;#039;&amp;#039;&amp;#039;mem&amp;#039;&amp;#039;&amp;#039; inside the memory instance &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;, the testbench may initialize the memory right at the beginning of the simulation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial $readmemb(&amp;quot;../../meminit.txt&amp;quot;, dut.mem);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the initialization is intended to be done for the implemented memory, the initialization process must be placed inside the memory module, in which case the memory array name is just the variable array to be initialized:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial $readmemb(&amp;quot;../../meminit.txt&amp;quot;, mem);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The filename, the first argument of &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; tasks, may be given either relative to the simulation folder (as in the previous two examples), or as the complete absolute filename, with the pathname starting from the linux root, &amp;#039;&amp;#039;&amp;#039;/&amp;#039;&amp;#039;&amp;#039;, for example &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;quot;/home/student/rom/meminit.txt&amp;quot;&amp;lt;/syntaxhighlight&amp;gt; if &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039; file resides in the project&amp;#039;s folder &amp;#039;&amp;#039;rom&amp;#039;&amp;#039;, created in the student&amp;#039;s home directory &amp;#039;&amp;#039;/home/student&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== Memory initialization file ===&lt;br /&gt;
&lt;br /&gt;
The initialization file is a text file with values written in binary (using &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; symbols) or in hexadecimal (using digits and letters &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; to &amp;#039;&amp;#039;&amp;#039;f&amp;#039;&amp;#039;&amp;#039;, either uppercase of lowercase). Values are separated by white spaces, tabs or newlines. Comments (started with &amp;#039;&amp;#039;&amp;#039;//&amp;#039;&amp;#039;&amp;#039; as in verilog) are ignored. An example of a binary initialization file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
// four values in binary text format&lt;br /&gt;
00000011&lt;br /&gt;
00001111&lt;br /&gt;
00111111&lt;br /&gt;
11111111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same initialization sequence, but given as a hexadecimal text file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
// four values in hexadecimal text format&lt;br /&gt;
03&lt;br /&gt;
0f&lt;br /&gt;
3f&lt;br /&gt;
ff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039;, in a newly created folder &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Create a new verilog file &amp;#039;&amp;#039;rom.sv&amp;#039;&amp;#039; that describes a 16x8 ROM using a vector variable and a continuous assignment.&lt;br /&gt;
* Create a testbench, &amp;#039;&amp;#039;&amp;#039;rom_tb&amp;#039;&amp;#039;&amp;#039;, that drives the input of &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039; with a sequence of addresses from 0 to highest one. Run simulation.&lt;br /&gt;
* Open a text editor, write some values in binary format on successive lines, and save the file into the &amp;#039;&amp;#039;rom&amp;#039;&amp;#039; folder with the name &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039;&lt;br /&gt;
* In the testbench module add an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process with a single statement that calls the system task for memory initialization. Run simulation.&lt;br /&gt;
* Assign the segments of a display to &amp;#039;&amp;#039;&amp;#039;dout&amp;#039;&amp;#039;&amp;#039;, and 4 switches, from SW3 to SW0, to &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
* In the &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039; module add an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process with a single statement that calls the system task for memory initialization. Pay atention how its second argument is given - the array variable is now directly accesible. Compile the project and program the FPGA.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
=== RAM - Read-Write Memory ===&lt;br /&gt;
&lt;br /&gt;
A synchronous memory reacts only on clock edges. The addresses are sampled at clock edges, the output changes also on clock edges, and the write is performed on clock edges too.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: Zlab8_ram.png]]&lt;br /&gt;
&lt;br /&gt;
The FPGA has dedicated blocks for memory implementation, the so called &amp;#039;&amp;#039;ram blocks&amp;#039;&amp;#039;, or &amp;#039;&amp;#039;ramblocks&amp;#039;&amp;#039;. In order for the synthesis to map a memory description to a &amp;#039;&amp;#039;ramblock&amp;#039;&amp;#039;, the sequential description must conform to a template:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(~we)                   // if write is enabled,&lt;br /&gt;
        mem[addr] &amp;lt;= wdata;   //     update the addressed location to wdata value&lt;br /&gt;
    rdata &amp;lt;= mem[addr];       // data read from the addressed location is transferred to the output&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039;, in a new folder &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Create a new verilog file &amp;#039;&amp;#039;ram.sv&amp;#039;&amp;#039; that describes a 16x4 RAM using a vector variable and a sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process that assigns to &amp;#039;&amp;#039;&amp;#039;rdata&amp;#039;&amp;#039;&amp;#039; output the value of the memory location selected by &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039;. In the same process update the same location with &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; value if &amp;#039;&amp;#039;&amp;#039;we&amp;#039;&amp;#039;&amp;#039; input is active (active at &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
* Create a testbench, &amp;#039;&amp;#039;&amp;#039;ram_tb&amp;#039;&amp;#039;&amp;#039;, which writes some data to four addresses, and then reads the same addresses in the same order, as indicated in the waveforms below. Don&amp;#039;t forget the clock! Run simulation and check that the written data are correctly read afterwards.&lt;br /&gt;
* Assign LEDs to the output, switches to the &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; inputs, a push button to the write enable input, and the board&amp;#039;s source clock to &amp;#039;&amp;#039;&amp;#039;clk&amp;#039;&amp;#039;&amp;#039; input.&lt;br /&gt;
* Compile, program the FPGA and test the RAM. Set switches to an address and a data value, then briefly push the write enable button. The LEDs will change accordingly. Change the address and data and push again the write enable button. Change back the address switches and see if the previously written configuration reappears on LED.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_ram_wave.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
=== Programmable display ===&lt;br /&gt;
&lt;br /&gt;
These application employs a dual port synchronous RAM. One port, the &amp;#039;&amp;#039;read port&amp;#039;&amp;#039;, is used to read data (&amp;#039;&amp;#039;&amp;#039;rdata&amp;#039;&amp;#039;&amp;#039;) from the memory, using the read address &amp;#039;&amp;#039;&amp;#039;raddr&amp;#039;&amp;#039;&amp;#039;. The other, the &amp;#039;&amp;#039;write port&amp;#039;&amp;#039;, accesses the same memory array, but using another address, &amp;#039;&amp;#039;&amp;#039;waddr&amp;#039;&amp;#039;&amp;#039;, to write &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; into. The write operation is performed only if the write enable pin (&amp;#039;&amp;#039;&amp;#039;we&amp;#039;&amp;#039;&amp;#039;) is active (here it is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
The data read from RAM is translated by the ROM into a 7 bit combination for the digit display. The RAM memory is read in sequence, address by address, changing the address at around each second. The sequence of 4 bit addresses are generated by a counter from which four suitable bits are chosen such that the rate of change is around 1 Hz.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_ramrom.png]]&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;ramrom&amp;#039;&amp;#039;&amp;#039;, in a newly created folder &amp;#039;&amp;#039;&amp;#039;ramrom&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* Copy the &amp;#039;&amp;#039;rom.v&amp;#039;&amp;#039; file from Exercise 1 into this folder.&lt;br /&gt;
* Add an initialization file to this folder, and ensures that &amp;#039;&amp;#039;rom.v&amp;#039;&amp;#039; initialization tasks reads it from the correct location.&lt;br /&gt;
* Copy the &amp;#039;&amp;#039;ram.v&amp;#039;&amp;#039; from from Exercise 2 into this folder. Change &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039; description to a dual RAM.&lt;br /&gt;
* Add &amp;#039;&amp;#039;&amp;#039;cnt32.v&amp;#039;&amp;#039;&amp;#039; to this project (you may reuse the &amp;#039;&amp;#039;&amp;#039;cnt32&amp;#039;&amp;#039;&amp;#039; module or file from the previous Application).&lt;br /&gt;
* Create the top-level design file, &amp;#039;&amp;#039;ramrom.v&amp;#039;&amp;#039;&amp;#039;, and instantiate the modules and connect them as indicated.&lt;br /&gt;
* Assign swithces, push button, clock source and digit display as shown.&lt;br /&gt;
* Compile, program the FPGA, and play with the board switches and buttons.&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Zlab8_ram.png&amp;diff=8050</id>
		<title>Fișier:Zlab8 ram.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Zlab8_ram.png&amp;diff=8050"/>
		<updated>2025-04-21T21:41:40Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_8&amp;diff=8049</id>
		<title>Applications 8</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_8&amp;diff=8049"/>
		<updated>2025-04-21T21:37:22Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: /* Memory initialization task */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A random access memory is an address-based data storage block, with a highly regular structure, which may be logically defined either as a bi-dimensional array of bits, or a uni-dimensional list of data words. Each row of the array, or each item of the list has a unique address. The addresses form a contiguous set of integers, starting from zero and running up to the highest address which defines the size of the address space, usually a power of 2. The memory capacity is therefore the number of address locations, N, times the width of the memory location (or of the memory word), W. These two numbers are the main parameters of any memory:&lt;br /&gt;
* N - the number of address locations, also the number of words;&lt;br /&gt;
* W - the number of bits for each location, or the data word width;&lt;br /&gt;
The storage capacity is N x W bits, but the memory capacity may also be given in bytes.&lt;br /&gt;
&lt;br /&gt;
Being a vector of words or a bidimensional array of bits, the memory could be described using a single bidimensional variable, usually declared as a vector of multibit &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; items. A memory array of N locations, with W bits per location is declared as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
logic [W-1:0] memory [0:N-1];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* the width of the word is declared as usual, with msb as the left index, &amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot; inline&amp;gt;[msb:0]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* the length of the memory is declared after the variable name, and starts with 0, the right index being the highest index of the vector, &amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot; inline&amp;gt;[0:endindex]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are two kinds of memories:&lt;br /&gt;
* read-only memories&lt;br /&gt;
* writable memories&lt;br /&gt;
&lt;br /&gt;
Memories can also be classified by their synchronous or asynchronous character:&lt;br /&gt;
* asynchronous - read data is immediately available at the output, write is performed as into a latch&lt;br /&gt;
* synchronous  - all operations are synchronized by one of the clock edges.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
=== ROM - Read-Only Memory ===&lt;br /&gt;
&lt;br /&gt;
It may be described as a purely combinational logic circuit, whose output (data) is a logic function of its input (address). The transcoder from [[Applications 4#transcoder|Applications 4]] is nothing else than a ROM, with &amp;#039;&amp;#039;&amp;#039;value&amp;#039;&amp;#039;&amp;#039; input acting as an address that selects a particular location from where data is read and sent out as &amp;#039;&amp;#039;&amp;#039;seg&amp;#039;&amp;#039;&amp;#039;. There it was described behaviorally with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that had a branch for each combination of input value bits.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_rom.png]]&lt;br /&gt;
&lt;br /&gt;
A more flexible description employs a single memory array, declared as a vector of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variables, and a statement that assigns the selected (addressed) element of the memory vector to the memory output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign dout = memory[addr];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Memory initialization task ===&lt;br /&gt;
&lt;br /&gt;
Memory arrays may be initialized with predefined values from a text file using verilog system tasks &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; reads predefined values given in binary, while &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; is used if values are given in hexadecimal. These verilog system tasks have two mandatory arguments and two optional arguments, in the following order:&lt;br /&gt;
# initialization filename, given as a string (between double quotes)&lt;br /&gt;
# the memory array variable name&lt;br /&gt;
# the start address (optional)&lt;br /&gt;
# the end address  (optional)&lt;br /&gt;
If the start and end addresses are not given, the memory array is initialized from the first address (address zero) until the last address or until the end of initialization file is reached.&lt;br /&gt;
&lt;br /&gt;
If the memory initialization file, &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039;, resides in the project&amp;#039;s folder, and the memory array to be initialized is &amp;#039;&amp;#039;&amp;#039;mem&amp;#039;&amp;#039;&amp;#039; inside the memory instance &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;, the testbench may initialize the memory right at the beginning of the simulation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial $readmemb(&amp;quot;../../meminit.txt&amp;quot;, dut.mem);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the initialization is intended to be done for the implemented memory, the initialization process must be placed inside the memory module, in which case the memory array name is just the variable array to be initialized:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial $readmemb(&amp;quot;../../meminit.txt&amp;quot;, mem);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The filename, the first argument of &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; tasks, may be given either relative to the simulation folder (as in the previous two examples), or as the complete absolute filename, with the pathname starting from the linux root, &amp;#039;&amp;#039;&amp;#039;/&amp;#039;&amp;#039;&amp;#039;, for example &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;quot;/home/student/rom/meminit.txt&amp;quot;&amp;lt;/syntaxhighlight&amp;gt; if &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039; file resides in the project&amp;#039;s folder &amp;#039;&amp;#039;rom&amp;#039;&amp;#039;, created in the student&amp;#039;s home directory &amp;#039;&amp;#039;/home/student&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== Memory initialization file ===&lt;br /&gt;
&lt;br /&gt;
The initialization file is a text file with values written in binary (using &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; symbols) or in hexadecimal (using digits and letters &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; to &amp;#039;&amp;#039;&amp;#039;f&amp;#039;&amp;#039;&amp;#039;, either uppercase of lowercase). Values are separated by white spaces, tabs or newlines. Comments (started with &amp;#039;&amp;#039;&amp;#039;//&amp;#039;&amp;#039;&amp;#039; as in verilog) are ignored. An example of a binary initialization file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
// four values in binary text format&lt;br /&gt;
00000011&lt;br /&gt;
00001111&lt;br /&gt;
00111111&lt;br /&gt;
11111111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same initialization sequence, but given as a hexadecimal text file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
// four values in hexadecimal text format&lt;br /&gt;
03&lt;br /&gt;
0f&lt;br /&gt;
3f&lt;br /&gt;
ff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039;, in a newly created folder &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Create a new verilog file &amp;#039;&amp;#039;rom.sv&amp;#039;&amp;#039; that describes a 16x8 ROM using a vector variable and a continuous assignment.&lt;br /&gt;
* Create a testbench, &amp;#039;&amp;#039;&amp;#039;rom_tb&amp;#039;&amp;#039;&amp;#039;, that drives the input of &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039; with a sequence of addresses from 0 to highest one. Run simulation.&lt;br /&gt;
* Open a text editor, write some values in binary format on successive lines, and save the file into the &amp;#039;&amp;#039;rom&amp;#039;&amp;#039; folder with the name &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039;&lt;br /&gt;
* In the testbench module add an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process with a single statement that calls the system task for memory initialization. Run simulation.&lt;br /&gt;
* Assign the segments of a display to &amp;#039;&amp;#039;&amp;#039;dout&amp;#039;&amp;#039;&amp;#039;, and 4 switches, from SW3 to SW0, to &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
* In the &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039; module add an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process with a single statement that calls the system task for memory initialization. Pay atention how its second argument is given - the array variable is now directly accesible. Compile the project and program the FPGA.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
=== RAM - Read-Write Memory ===&lt;br /&gt;
&lt;br /&gt;
A synchronous memory reacts only on clock edges. The addresses are sampled at clock edges, the output changes also on clock edges, and the write is performed on clock edges too.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_ram.png]]&lt;br /&gt;
&lt;br /&gt;
The FPGA has dedicated blocks for memory implementation, the so called &amp;#039;&amp;#039;ram blocks&amp;#039;&amp;#039;, or &amp;#039;&amp;#039;ramblocks&amp;#039;&amp;#039;. In order for the synthesis to map a memory description to a &amp;#039;&amp;#039;ramblock&amp;#039;&amp;#039;, the sequential description must conform to a template:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(~we)                   // if write is enabled,&lt;br /&gt;
        mem[addr] &amp;lt;= wdata;   //     update the addressed location to wdata value&lt;br /&gt;
    rdata &amp;lt;= mem[addr];       // data read from the addressed location is transferred to the output&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039;, in a new folder &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Create a new verilog file &amp;#039;&amp;#039;ram.sv&amp;#039;&amp;#039; that describes a 16x4 RAM using a vector variable and a sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process that assigns to &amp;#039;&amp;#039;&amp;#039;rdata&amp;#039;&amp;#039;&amp;#039; output the value of the memory location selected by &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039;. In the same process update the same location with &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; value if &amp;#039;&amp;#039;&amp;#039;we&amp;#039;&amp;#039;&amp;#039; input is active (active at &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
* Create a testbench, &amp;#039;&amp;#039;&amp;#039;ram_tb&amp;#039;&amp;#039;&amp;#039;, which writes some data to four addresses, and then reads the same addresses in the same order, as indicated in the waveforms below. Don&amp;#039;t forget the clock! Run simulation and check that the written data are correctly read afterwards.&lt;br /&gt;
* Assign LEDs to the output, switches to the &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; inputs, a push button to the write enable input, and the board&amp;#039;s source clock to &amp;#039;&amp;#039;&amp;#039;clk&amp;#039;&amp;#039;&amp;#039; input.&lt;br /&gt;
* Compile, program the FPGA and test the RAM. Set switches to an address and a data value, then briefly push the write enable button. The LEDs will change accordingly. Change the address and data and push again the write enable button. Change back the address switches and see if the previously written configuration reappears on LED.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_ram_wave.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
=== Programmable display ===&lt;br /&gt;
&lt;br /&gt;
These application employs a dual port synchronous RAM. One port, the &amp;#039;&amp;#039;read port&amp;#039;&amp;#039;, is used to read data (&amp;#039;&amp;#039;&amp;#039;rdata&amp;#039;&amp;#039;&amp;#039;) from the memory, using the read address &amp;#039;&amp;#039;&amp;#039;raddr&amp;#039;&amp;#039;&amp;#039;. The other, the &amp;#039;&amp;#039;write port&amp;#039;&amp;#039;, accesses the same memory array, but using another address, &amp;#039;&amp;#039;&amp;#039;waddr&amp;#039;&amp;#039;&amp;#039;, to write &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; into. The write operation is performed only if the write enable pin (&amp;#039;&amp;#039;&amp;#039;we&amp;#039;&amp;#039;&amp;#039;) is active (here it is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
The data read from RAM is translated by the ROM into a 7 bit combination for the digit display. The RAM memory is read in sequence, address by address, changing the address at around each second. The sequence of 4 bit addresses are generated by a counter from which four suitable bits are chosen such that the rate of change is around 1 Hz.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_ramrom.png]]&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;ramrom&amp;#039;&amp;#039;&amp;#039;, in a newly created folder &amp;#039;&amp;#039;&amp;#039;ramrom&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* Copy the &amp;#039;&amp;#039;rom.v&amp;#039;&amp;#039; file from Exercise 1 into this folder.&lt;br /&gt;
* Add an initialization file to this folder, and ensures that &amp;#039;&amp;#039;rom.v&amp;#039;&amp;#039; initialization tasks reads it from the correct location.&lt;br /&gt;
* Copy the &amp;#039;&amp;#039;ram.v&amp;#039;&amp;#039; from from Exercise 2 into this folder. Change &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039; description to a dual RAM.&lt;br /&gt;
* Add &amp;#039;&amp;#039;&amp;#039;cnt32.v&amp;#039;&amp;#039;&amp;#039; to this project (you may reuse the &amp;#039;&amp;#039;&amp;#039;cnt32&amp;#039;&amp;#039;&amp;#039; module or file from the previous Application).&lt;br /&gt;
* Create the top-level design file, &amp;#039;&amp;#039;ramrom.v&amp;#039;&amp;#039;&amp;#039;, and instantiate the modules and connect them as indicated.&lt;br /&gt;
* Assign swithces, push button, clock source and digit display as shown.&lt;br /&gt;
* Compile, program the FPGA, and play with the board switches and buttons.&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Applications_8&amp;diff=8048</id>
		<title>Applications 8</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Applications_8&amp;diff=8048"/>
		<updated>2025-04-21T21:36:48Z</updated>

		<summary type="html">&lt;p&gt;Zhascsi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A random access memory is an address-based data storage block, with a highly regular structure, which may be logically defined either as a bi-dimensional array of bits, or a uni-dimensional list of data words. Each row of the array, or each item of the list has a unique address. The addresses form a contiguous set of integers, starting from zero and running up to the highest address which defines the size of the address space, usually a power of 2. The memory capacity is therefore the number of address locations, N, times the width of the memory location (or of the memory word), W. These two numbers are the main parameters of any memory:&lt;br /&gt;
* N - the number of address locations, also the number of words;&lt;br /&gt;
* W - the number of bits for each location, or the data word width;&lt;br /&gt;
The storage capacity is N x W bits, but the memory capacity may also be given in bytes.&lt;br /&gt;
&lt;br /&gt;
Being a vector of words or a bidimensional array of bits, the memory could be described using a single bidimensional variable, usually declared as a vector of multibit &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; items. A memory array of N locations, with W bits per location is declared as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
logic [W-1:0] memory [0:N-1];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* the width of the word is declared as usual, with msb as the left index, &amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot; inline&amp;gt;[msb:0]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* the length of the memory is declared after the variable name, and starts with 0, the right index being the highest index of the vector, &amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot; inline&amp;gt;[0:endindex]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are two kinds of memories:&lt;br /&gt;
* read-only memories&lt;br /&gt;
* writable memories&lt;br /&gt;
&lt;br /&gt;
Memories can also be classified by their synchronous or asynchronous character:&lt;br /&gt;
* asynchronous - read data is immediately available at the output, write is performed as into a latch&lt;br /&gt;
* synchronous  - all operations are synchronized by one of the clock edges.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 1 ==&lt;br /&gt;
=== ROM - Read-Only Memory ===&lt;br /&gt;
&lt;br /&gt;
It may be described as a purely combinational logic circuit, whose output (data) is a logic function of its input (address). The transcoder from [[Applications 4#transcoder|Applications 4]] is nothing else than a ROM, with &amp;#039;&amp;#039;&amp;#039;value&amp;#039;&amp;#039;&amp;#039; input acting as an address that selects a particular location from where data is read and sent out as &amp;#039;&amp;#039;&amp;#039;seg&amp;#039;&amp;#039;&amp;#039;. There it was described behaviorally with a &amp;#039;&amp;#039;&amp;#039;case&amp;#039;&amp;#039;&amp;#039; statement that had a branch for each combination of input value bits.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_rom.png]]&lt;br /&gt;
&lt;br /&gt;
A more flexible description employs a single memory array, declared as a vector of &amp;#039;&amp;#039;&amp;#039;reg&amp;#039;&amp;#039;&amp;#039; variables, and a statement that assigns the selected (addressed) element of the memory vector to the memory output.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
assign dout = memory[addr];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Memory initialization task ===&lt;br /&gt;
&lt;br /&gt;
Memory arrays may be initialized with predefined values from a text file using verilog system tasks &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039;. &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; reads predefined values given in binary, while &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; is used if values are given in hexadecimal. These verilog system tasks have two mandatory arguments and two optional arguments, in the following order:&lt;br /&gt;
# initialization filename, given as a string (between double quotes)&lt;br /&gt;
# the memory array variable name&lt;br /&gt;
# the start address (optional)&lt;br /&gt;
# the end address  (optional)&lt;br /&gt;
If the start and end addresses are not given, the memory array is initialized from the first address (address zero) until the last address or until the end of initialization file is reached.&lt;br /&gt;
&lt;br /&gt;
If the memory initialization file, &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039;, resides in the project&amp;#039;s folder, and the memory array to be initialized is &amp;#039;&amp;#039;&amp;#039;mem&amp;#039;&amp;#039;&amp;#039; inside the memory instance &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;, the testbench may initialize the memory right at the beginning of the simulation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
initial $readmemb(&amp;quot;../../meminit.txt&amp;quot;, dut.mem);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the initialization is intended to be done for the implemented memory, the initialization process must be placed inside the memory module, in which case the memory array name is just the variable array to be initialized:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
initial $readmemb(&amp;quot;../../meminit.txt&amp;quot;, mem);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The filename, the first argument of &amp;#039;&amp;#039;&amp;#039;$readmemb&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;$readmemh&amp;#039;&amp;#039;&amp;#039; tasks, may be given either relative to the simulation folder (as in the previous two examples), or as the complete absolute filename, with the pathname starting from the linux root, &amp;#039;&amp;#039;&amp;#039;/&amp;#039;&amp;#039;&amp;#039;, for example &amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot; inline&amp;gt;&amp;quot;/home/student/rom/meminit.txt&amp;quot;&amp;lt;/syntaxhighlight&amp;gt; if &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039; file resides in the project&amp;#039;s folder &amp;#039;&amp;#039;rom&amp;#039;&amp;#039;, created in the student&amp;#039;s home directory &amp;#039;&amp;#039;/home/student&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== Memory initialization file ===&lt;br /&gt;
&lt;br /&gt;
The initialization file is a text file with values written in binary (using &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039; symbols) or in hexadecimal (using digits and letters &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; to &amp;#039;&amp;#039;&amp;#039;f&amp;#039;&amp;#039;&amp;#039;, either uppercase of lowercase). Values are separated by white spaces, tabs or newlines. Comments (started with &amp;#039;&amp;#039;&amp;#039;//&amp;#039;&amp;#039;&amp;#039; as in verilog) are ignored. An example of a binary initialization file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
// four values in binary text format&lt;br /&gt;
00000011&lt;br /&gt;
00001111&lt;br /&gt;
00111111&lt;br /&gt;
11111111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same initialization sequence, but given as a hexadecimal text file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang = &amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
// four values in hexadecimal text format&lt;br /&gt;
03&lt;br /&gt;
0f&lt;br /&gt;
3f&lt;br /&gt;
ff&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039;, in a newly created folder &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Create a new verilog file &amp;#039;&amp;#039;rom.sv&amp;#039;&amp;#039; that describes a 16x8 ROM using a vector variable and a continuous assignment.&lt;br /&gt;
* Create a testbench, &amp;#039;&amp;#039;&amp;#039;rom_tb&amp;#039;&amp;#039;&amp;#039;, that drives the input of &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039; with a sequence of addresses from 0 to highest one. Run simulation.&lt;br /&gt;
* Open a text editor, write some values in binary format on successive lines, and save the file into the &amp;#039;&amp;#039;rom&amp;#039;&amp;#039; folder with the name &amp;#039;&amp;#039;meminit.txt&amp;#039;&amp;#039;&lt;br /&gt;
* In the testbench module add an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process with a single statement that calls the system task for memory initialization. Run simulation.&lt;br /&gt;
* Assign the segments of a display to &amp;#039;&amp;#039;&amp;#039;dout&amp;#039;&amp;#039;&amp;#039;, and 4 switches, from SW3 to SW0, to &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
* In the &amp;#039;&amp;#039;&amp;#039;rom&amp;#039;&amp;#039;&amp;#039; module add an &amp;#039;&amp;#039;&amp;#039;initial&amp;#039;&amp;#039;&amp;#039; process with a single statement that calls the system task for memory initialization. Pay atention how its second argument is given - the array variable is now directly accesible. Compile the project and program the FPGA.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exercise 2 ==&lt;br /&gt;
=== RAM - Read-Write Memory ===&lt;br /&gt;
&lt;br /&gt;
A synchronous memory reacts only on clock edges. The addresses are sampled at clock edges, the output changes also on clock edges, and the write is performed on clock edges too.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_ram.png]]&lt;br /&gt;
&lt;br /&gt;
The FPGA has dedicated blocks for memory implementation, the so called &amp;#039;&amp;#039;ram blocks&amp;#039;&amp;#039;, or &amp;#039;&amp;#039;ramblocks&amp;#039;&amp;#039;. In order for the synthesis to map a memory description to a &amp;#039;&amp;#039;ramblock&amp;#039;&amp;#039;, the sequential description must conform to a template:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;SystemVerilog&amp;quot;&amp;gt;&lt;br /&gt;
always @(posedge clk) begin&lt;br /&gt;
    if(~we)                   // if write is enabled,&lt;br /&gt;
        mem[addr] &amp;lt;= wdata;   //     update the addressed location to wdata value&lt;br /&gt;
    rdata &amp;lt;= mem[addr];       // data read from the addressed location is transferred to the output&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039;, in a new folder &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Create a new verilog file &amp;#039;&amp;#039;ram.sv&amp;#039;&amp;#039; that describes a 16x4 RAM using a vector variable and a sequential &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; process that assigns to &amp;#039;&amp;#039;&amp;#039;rdata&amp;#039;&amp;#039;&amp;#039; output the value of the memory location selected by &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039;. In the same process update the same location with &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; value if &amp;#039;&amp;#039;&amp;#039;we&amp;#039;&amp;#039;&amp;#039; input is active (active at &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
* Create a testbench, &amp;#039;&amp;#039;&amp;#039;ram_tb&amp;#039;&amp;#039;&amp;#039;, which writes some data to four addresses, and then reads the same addresses in the same order, as indicated in the waveforms below. Don&amp;#039;t forget the clock! Run simulation and check that the written data are correctly read afterwards.&lt;br /&gt;
* Assign LEDs to the output, switches to the &amp;#039;&amp;#039;&amp;#039;addr&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; inputs, a push button to the write enable input, and the board&amp;#039;s source clock to &amp;#039;&amp;#039;&amp;#039;clk&amp;#039;&amp;#039;&amp;#039; input.&lt;br /&gt;
* Compile, program the FPGA and test the RAM. Set switches to an address and a data value, then briefly push the write enable button. The LEDs will change accordingly. Change the address and data and push again the write enable button. Change back the address switches and see if the previously written configuration reappears on LED.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_ram_wave.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Exercise 3 ==&lt;br /&gt;
=== Programmable display ===&lt;br /&gt;
&lt;br /&gt;
These application employs a dual port synchronous RAM. One port, the &amp;#039;&amp;#039;read port&amp;#039;&amp;#039;, is used to read data (&amp;#039;&amp;#039;&amp;#039;rdata&amp;#039;&amp;#039;&amp;#039;) from the memory, using the read address &amp;#039;&amp;#039;&amp;#039;raddr&amp;#039;&amp;#039;&amp;#039;. The other, the &amp;#039;&amp;#039;write port&amp;#039;&amp;#039;, accesses the same memory array, but using another address, &amp;#039;&amp;#039;&amp;#039;waddr&amp;#039;&amp;#039;&amp;#039;, to write &amp;#039;&amp;#039;&amp;#039;wdata&amp;#039;&amp;#039;&amp;#039; into. The write operation is performed only if the write enable pin (&amp;#039;&amp;#039;&amp;#039;we&amp;#039;&amp;#039;&amp;#039;) is active (here it is active &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
The data read from RAM is translated by the ROM into a 7 bit combination for the digit display. The RAM memory is read in sequence, address by address, changing the address at around each second. The sequence of 4 bit addresses are generated by a counter from which four suitable bits are chosen such that the rate of change is around 1 Hz.&lt;br /&gt;
&lt;br /&gt;
[[Fișier: appl8_ramrom.png]]&lt;br /&gt;
&lt;br /&gt;
* Start a new project, &amp;#039;&amp;#039;&amp;#039;ramrom&amp;#039;&amp;#039;&amp;#039;, in a newly created folder &amp;#039;&amp;#039;&amp;#039;ramrom&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* Copy the &amp;#039;&amp;#039;rom.v&amp;#039;&amp;#039; file from Exercise 1 into this folder.&lt;br /&gt;
* Add an initialization file to this folder, and ensures that &amp;#039;&amp;#039;rom.v&amp;#039;&amp;#039; initialization tasks reads it from the correct location.&lt;br /&gt;
* Copy the &amp;#039;&amp;#039;ram.v&amp;#039;&amp;#039; from from Exercise 2 into this folder. Change &amp;#039;&amp;#039;&amp;#039;ram&amp;#039;&amp;#039;&amp;#039; description to a dual RAM.&lt;br /&gt;
* Add &amp;#039;&amp;#039;&amp;#039;cnt32.v&amp;#039;&amp;#039;&amp;#039; to this project (you may reuse the &amp;#039;&amp;#039;&amp;#039;cnt32&amp;#039;&amp;#039;&amp;#039; module or file from the previous Application).&lt;br /&gt;
* Create the top-level design file, &amp;#039;&amp;#039;ramrom.v&amp;#039;&amp;#039;&amp;#039;, and instantiate the modules and connect them as indicated.&lt;br /&gt;
* Assign swithces, push button, clock source and digit display as shown.&lt;br /&gt;
* Compile, program the FPGA, and play with the board switches and buttons.&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zhascsi</name></author>
	</entry>
</feed>