<?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=Mihai.antonescu</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=Mihai.antonescu"/>
	<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php/Special:Contribu%C8%9Bii/Mihai.antonescu"/>
	<updated>2026-05-22T05:14:04Z</updated>
	<subtitle>Contribuții utilizator</subtitle>
	<generator>MediaWiki 1.35.14</generator>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_12_:_Exercitii_cu_circuite_secventiale&amp;diff=8352</id>
		<title>CID aplicatii 12 : Exercitii cu circuite secventiale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_12_:_Exercitii_cu_circuite_secventiale&amp;diff=8352"/>
		<updated>2026-05-21T10:14:09Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exercitii */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 2 in anii anteriori.&lt;br /&gt;
&lt;br /&gt;
Unele exercitii contin si automate. Daca acestea nu au fost inca predate, puteti ignora partea aceea de circuit.&lt;br /&gt;
&lt;br /&gt;
Dupa cum se poate observa, exemplele sunt diverse ca domeniu de aplicabilitate. Prin asta se doreste a se arata importanta si diversitatea circuitelor digitale in societatea moderna.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: password checker===&lt;br /&gt;
&lt;br /&gt;
SystemVerilog suporta codul ASCII deci puteti introduce si litere/string-uri care vor fi tratate prin reprezentarea lor binara.&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/5/5c/Subiect_l2_password_checker.pdf password_checker.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: PWM static pe RGB ===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/f/f2/Subiect_pwm_l2.pdf PWM_static_pe_RGB.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: calculator de siruri dupa formula data===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/a/a2/Subiect_l2_sir_calculator.pdf calculator_siruri.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: UART tx - structural===&lt;br /&gt;
&lt;br /&gt;
UART este un standard pentru transmisiune de date seriale. Pentru o descriere a protocolului puteti citi: [https://www.circuitbasics.com/basics-uart-communication/ functionare_uart]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/d/d0/Subiect_l2_uart_tx.pdf uart_tx.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: UART rx - behavioural=== &lt;br /&gt;
&lt;br /&gt;
Daca ati inteles cum functioneaza mecanismul de UART (si pentru a testa functionarea TX de la exercitiul anterior) puteti scrie modulul de RX (receiver) al protocolului, astfel incat cele 2 sa comunice intre ele.&lt;br /&gt;
&lt;br /&gt;
La nivel de TB ar fi amandoua instantiate si conectate intre ele. &lt;br /&gt;
&lt;br /&gt;
UART RX ar trebui sa scoata un puls al semnalului &amp;quot;valid&amp;quot; impreuna cu 8 biti de date daca transmisiunea a fost efectuata cu succes, datele care ies din el fiind cele care au intrat in modulul de tx. &lt;br /&gt;
&lt;br /&gt;
Pentru a compara abordarea structurala cu cea comportamentala, acest modul se doreste a fi facut comportamental.&lt;br /&gt;
In always-urile acestuia vor aparea mecanisme de numarare care practic alcatuiesc un mic FSM de control. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: microcontrollere - oscillator control register=== &lt;br /&gt;
&lt;br /&gt;
Acest subiect prezinta un modul simplificat al mecanismului de control al oscilatorului de pe un microcontroller. Acest modul controleaza generarea smenalului de ceas ce se propaga catre microcontroller si deci viteza la care sistemul va functiona.&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/0/09/Subiect_l2_uc_osccon.pdf uc_osccon.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 7: Led care se invarte===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/a/af/L2_led_care_se_invarte.pdf Led_care_se_invarte.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 8: Media dintre cel mai mic și cel mai mare număr===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/0/0c/Lucrarea2_Subiect_pentru_wiki.pdf Media_dintre_cel_mai_mic_si_cel_mai_mare_numar]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 9: Fifo facut din 2 stive===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2f/Subiect_fifo_din_2_stive.pdf Fifo_facut_din_2_stive]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Subiect_fifo_din_2_stive.pdf&amp;diff=8351</id>
		<title>Fișier:Subiect fifo din 2 stive.pdf</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Subiect_fifo_din_2_stive.pdf&amp;diff=8351"/>
		<updated>2026-05-21T10:13:46Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_8_:_Registre_si_memorii_RAM&amp;diff=8340</id>
		<title>CID aplicatii 8 : Registre si memorii RAM</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_8_:_Registre_si_memorii_RAM&amp;diff=8340"/>
		<updated>2026-04-29T21:02:04Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Teorie */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are scopul de a prezenta circuitele secventiale simple: registre si memorii RAM. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pornind de la bistabilii prezentati/construiti in laboratorul anterior, apare notiunea de registru, acesta fiind o grupare de bistabili. Astfel in loc sa se memoreze un singur bit de informatie (bistabil), se pot memora acum numere pe mai multi biti (registru).&lt;br /&gt;
&lt;br /&gt;
Din exterior, un registru este vazut astfel: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Registru_exterior_view.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Semnalul de &amp;quot;clock&amp;quot; controleaza sincronizarea registrilor din tot sistemul.&lt;br /&gt;
:Semnalul de &amp;quot;reset&amp;quot; aduce registrul la o valoare initiala (uzual 0).&lt;br /&gt;
:Semnalul de &amp;quot;we&amp;quot; (write enable) controleaza salvarea unor date noi. Cand acesta este activ, data de pe intrarea &amp;quot;data_in&amp;quot; se salveaza in registru.&lt;br /&gt;
:Semnalul &amp;quot;data_in&amp;quot; reprezinta datele ce se doresc a fi scrise in registru.&lt;br /&gt;
:Semnalul &amp;quot;data_out&amp;quot; reprezinta valoarea stocata in registru.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Semnalele &amp;quot;data_in&amp;quot; si &amp;quot;data_out&amp;quot; pot fi pe oricat de multi biti se doreste, in mod uzual multipli de 8.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pornind de la notiunea de registru (care poate fi vazut ca o memorie cu o locatie si avand &amp;quot;m&amp;quot; biti) se doreste cresterea acestei memorii astfel incat aceasta sa curpinda mai multe locatii adresabile, unde se pot stoca date. Adaugand mai multi registri in paralel, unul langa altul, si cateva circuite de tip mux/demux se poate obtine o memorie de tip RAM (Random Access Memory), cu &amp;quot;m&amp;quot; locatii de &amp;quot;n&amp;quot; biti fiecare. Aceste memorii se cheama &amp;quot;Random Access&amp;quot; deoarece permit si scriere si citire in/din orice locatie.&lt;br /&gt;
&lt;br /&gt;
Din exterior, o memorie RAM este vazuta astfel: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Ram_mXn_1read_1write_exterior_view.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Semnalele acestui circuit se pot imparti in semnale ce tin de interfata de scriere sau interfata de citire si mai apoi in semnale de date si semnale de control. Interfata sa este: &lt;br /&gt;
	&lt;br /&gt;
:Semnalul de &amp;quot;clock&amp;quot;: controleaza sincronizarea registrilor din memorie.&lt;br /&gt;
:Semnalul &amp;quot;addr_read&amp;quot;: adresa de la care se citesc datele. &lt;br /&gt;
:Semnalul &amp;quot;data_read&amp;quot;: data ce se citeste.&lt;br /&gt;
:Semnalul de &amp;quot;we&amp;quot;: semnal de control ce controleaza activarea scrierii. Scrierea are loc doar cand acest semnal este activ.&lt;br /&gt;
:Semnalul &amp;quot;addr_write&amp;quot;: adresa la care se scriu datele.&lt;br /&gt;
:Semnalul &amp;quot;data_write&amp;quot;: data ce urmeaza a fi scrisa atunci cand semnalul &amp;quot;we&amp;quot; este activ.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Orice memorie are &amp;quot;m&amp;quot; locatii de &amp;quot;n&amp;quot; biti. Semnalele de &amp;quot;data_read&amp;quot; si &amp;quot;data_write&amp;quot; au aceeasi dimensiune, &amp;quot;n&amp;quot;, numarul de biti ai fiecarei locatii. Semnalele de adresa au dimensiunea log2(m). Pentru o memorie cu 16 locatii va fi nevoie de 4 biti de adresa pentru a putea selecta orice locatie, pentru 32 locatii 5b s.a.m.d. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: In unele situatii se mai poate pune un registru suplimentar pe iesirea datelor, cu rol in sincronizare si evitarea timpilor de propagare prea lungi intre elemente de memorare (ajuta implementarea conceptului de pipeline).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Exista mai multe variante de memorii RAM (cu registru pe iesire/fara, multiport/single port citire, adrese separate sau nu pentru citire/scriere). Cea de mai sus este o memorie cu un singur port de citire, fara registru suplimentar pe iesire, ce foloseste adrese distincte pentru citire si pentru scriere (la fel de bine se poate lucra si cu o singura adresa, comuna pentru scriere si citire).&lt;br /&gt;
 &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Memoriile RAM pot sa nu aiba reset, utilizatorul trebuie apoi sa aiba grija sa citeasca doar din locatii scrise de el anterior.&lt;br /&gt;
In mod uzual ele nu au reset.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
&lt;br /&gt;
===Exemplul 1 : Registrul===&lt;br /&gt;
&lt;br /&gt;
In urmatorul exemplu se implementeaza registrul descris mai sus:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea registrului (fisierul register_8b.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module register_8b&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset, // activ pe &amp;quot;1&amp;quot;&lt;br /&gt;
		input logic we,&lt;br /&gt;
		input logic [7:0] data_in, &lt;br /&gt;
		output logic [7:0] data_out // data_out are aceeasi dimensiune ca data_in&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
always_ff @(posedge clock) // clock sincronizeaza actiunile circuitului&lt;br /&gt;
begin    // doar pe edge-ul pozitiv circuitul actioneaza&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
    	begin&lt;br /&gt;
    	data_out &amp;lt;= 0;&lt;br /&gt;
    	end&lt;br /&gt;
    else&lt;br /&gt;
    	begin&lt;br /&gt;
		if(we == 1) // comanda de scriere&lt;br /&gt;
			begin&lt;br /&gt;
			data_out &amp;lt;= data_in;&lt;br /&gt;
			end&lt;br /&gt;
		else // puteam sa omit acest else&lt;br /&gt;
			begin&lt;br /&gt;
			data_out &amp;lt;= data_out; // raman datele salvate anterior&lt;br /&gt;
			end&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;
&lt;br /&gt;
Un alt mod de a scrie un registru este dat mai jos, cu observatia ca aici am pus semnalul de reset activ in logica negativa:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea registrului (fisierul register_8b_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module register_8b_v2&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset_n, // activ in &amp;quot;0&amp;quot;&lt;br /&gt;
		// uzual semnalel cu n in fata sau la sfarsit sunt in logica negativa: nreset, resetn&lt;br /&gt;
		input logic we,&lt;br /&gt;
		input logic [7:0] data_in,&lt;br /&gt;
		output logic [7:0] data_out&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
logic [7:0] memorie_efectiva;   &lt;br /&gt;
&lt;br /&gt;
assign data_out = memorie_efectiva;&lt;br /&gt;
    &lt;br /&gt;
always_ff @(posedge clock)&lt;br /&gt;
begin  &lt;br /&gt;
	if( reset_n == 0) &lt;br /&gt;
		begin&lt;br /&gt;
		memorie_efectiva &amp;lt;= 0;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		begin&lt;br /&gt;
		if(we == 1)&lt;br /&gt;
			begin&lt;br /&gt;
			memorie_efectiva &amp;lt;= data_in;&lt;br /&gt;
			end&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;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea test bench-ului registrului pe 8biti: (fisierul register_8b_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module register_8b_tb();&lt;br /&gt;
&lt;br /&gt;
logic clock_tb;&lt;br /&gt;
logic reset_tb;&lt;br /&gt;
logic we_tb;&lt;br /&gt;
logic [7:0] data_in_tb;&lt;br /&gt;
logic [7:0] data_out_tb;&lt;br /&gt;
&lt;br /&gt;
register_8b dut 	// varianta cu reset activ in &amp;quot;1&amp;quot;&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock_tb),&lt;br /&gt;
		.reset(reset_tb),&lt;br /&gt;
		.we(we_tb),&lt;br /&gt;
		.data_in(data_in_tb),&lt;br /&gt;
		.data_out(data_out_tb)&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	clock_tb = 0;&lt;br /&gt;
	forever &lt;br /&gt;
		begin&lt;br /&gt;
		#5 clock_tb = ~clock_tb; // perioada totala 10 !!!&lt;br /&gt;
		end&lt;br /&gt;
end    &lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	reset_tb &amp;lt;= 0;&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	data_in_tb &amp;lt;= 0;&lt;br /&gt;
		// observatie: pana la primul reset sau prima scriere, valoarea din registru va fi necunoscuta (in simulare X)&lt;br /&gt;
		&lt;br /&gt;
		// dau reset la circuit&lt;br /&gt;
	@(posedge clock_tb); // astept sa treaca 1 clock cycle&lt;br /&gt;
	reset_tb &amp;lt;= 1;	&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	reset_tb &amp;lt;= 0;&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		// incep sa fac scrieri&lt;br /&gt;
	we_tb &amp;lt;= 1;&lt;br /&gt;
	data_in_tb &amp;lt;= 5;&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	data_in_tb &amp;lt;= 10;	// scrierea asta nu se face deoarece nu am write enable activ&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_in_tb &amp;lt;= 11;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_in_tb &amp;lt;= 12;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb = 1;&lt;br /&gt;
	data_in_tb &amp;lt;= 42;	// asta da&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_in_tb &amp;lt;= 51;	// si asta da&lt;br /&gt;
	@(posedge clock_tb);	&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&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;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Memorie RAM===&lt;br /&gt;
	&lt;br /&gt;
In urmatorul exemplu se implementeaza memoria RAM descrisa mai sus, particularizata pentru 64 de locatii a cate 8b fiecare:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea memoriei RAM: (fisierul ram64x8_v1.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module ram64x8_v1&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		//interfata de citire&lt;br /&gt;
			input logic [5:0] addr_read, // 64 locatii =&amp;gt; 6 biti de adresa &lt;br /&gt;
			output logic [7:0] data_read, // fiecare locatie are 8b  &lt;br /&gt;
		// interfata de scriere&lt;br /&gt;
			input logic we,&lt;br /&gt;
			input logic [5:0] addr_write,&lt;br /&gt;
			input logic [7:0] data_write&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic [7:0] memorie_efectiva [0:63]; // memorie cu locatiile de la 0 la 63, fiecare avand 8 biti    &lt;br /&gt;
&lt;br /&gt;
assign data_read = memorie_efectiva[addr_read]; // fara registru pe iesire =&amp;gt; citire asincrona fata de clock &lt;br /&gt;
    &lt;br /&gt;
always_ff @(posedge clock)&lt;br /&gt;
begin    &lt;br /&gt;
    if(we == 1)&lt;br /&gt;
    	begin&lt;br /&gt;
    	memorie_efectiva[addr_write] &amp;lt;= data_write; // scriu la locatia data de &amp;quot;addr_write&amp;quot; din memoria efectiva datele &amp;quot;data_write&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;
Acesta va fi folosit si pe post de modul de &amp;quot;top&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Echivalent se poate folosi si sintaxa cu always ca mai jos.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea memoriei RAM: (fisierul ram64x8_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module ram64x8_v2 // varianta cu always combinational pe citire&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		//interfata de citire&lt;br /&gt;
			input logic [5:0] addr_read,&lt;br /&gt;
			output logic [7:0] data_read,&lt;br /&gt;
		// interfata de scriere&lt;br /&gt;
			input logic we,&lt;br /&gt;
			input logic [5:0] addr_write,&lt;br /&gt;
			input logic [7:0] data_write&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic [7:0] memorie_efectiva [0:63];  &lt;br /&gt;
&lt;br /&gt;
always_comb //  citire asincrona fata de clock &lt;br /&gt;
begin&lt;br /&gt;
	data_read = memorie_efectiva[addr_read]; &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock)&lt;br /&gt;
begin    &lt;br /&gt;
    if(we == 1)&lt;br /&gt;
    	begin&lt;br /&gt;
    	memorie_efectiva[addr_write] &amp;lt;= data_write; // scriu la locatia data de &amp;quot;addr_write&amp;quot; din memoria efectiva datele &amp;quot;data_write&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;
&amp;#039;&amp;#039;&amp;#039;Descrierea test bench-ului memoriei RAM: (fisierul ram64x8_v1_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module ram64x8_tb();&lt;br /&gt;
&lt;br /&gt;
logic clock_tb;&lt;br /&gt;
logic [5:0] addr_read_tb;&lt;br /&gt;
logic [7:0] data_read_tb;&lt;br /&gt;
logic we_tb;&lt;br /&gt;
logic [5:0] addr_write_tb;&lt;br /&gt;
logic [7:0] data_write_tb;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ram64x8_v1 dut&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock_tb),&lt;br /&gt;
		//interfata de citire&lt;br /&gt;
			.addr_read(addr_read_tb), // 64 locatii =&amp;gt; 6 biti de adresa &lt;br /&gt;
			.data_read(data_read_tb), // fiecare locatie are 8b  &lt;br /&gt;
		// interfata de scriere&lt;br /&gt;
			.we(we_tb),&lt;br /&gt;
			.addr_write(addr_write_tb),&lt;br /&gt;
			.data_write(data_write_tb)&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	clock_tb = 0;&lt;br /&gt;
	forever &lt;br /&gt;
		begin&lt;br /&gt;
		#5 clock_tb = ~clock_tb; // perioada totala 10 !!!&lt;br /&gt;
		end&lt;br /&gt;
end    &lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	data_write_tb &amp;lt;= 0;&lt;br /&gt;
	addr_read_tb &amp;lt;= 0; // citind de la o adresa nescrisa inca, iesirea e necunoscuta&lt;br /&gt;
	addr_write_tb &amp;lt;= 0;&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		// incep sa fac scrieri&lt;br /&gt;
	we_tb &amp;lt;= 1;	// scriu data 5 la adresa 10&lt;br /&gt;
	addr_write_tb &amp;lt;= 10;&lt;br /&gt;
	data_write_tb &amp;lt;= 5;&lt;br /&gt;
	addr_read_tb &amp;lt;= 11; // citind de la o adresa nescrisa inca, iesirea e necunoscuta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb &amp;lt;= 0;			// scrierea asta nu se face deoarece nu am write enable activ	&lt;br /&gt;
	addr_write_tb &amp;lt;= 11;&lt;br /&gt;
	data_write_tb &amp;lt;= 10;	&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_write_tb &amp;lt;= 11;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_write_tb &amp;lt;= 12;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb &amp;lt;= 1;&lt;br /&gt;
	addr_write_tb &amp;lt;= 20; // scriere ok &lt;br /&gt;
	data_write_tb &amp;lt;= 42;	// scriu data 42 la adresa 20&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_write_tb &amp;lt;= 51;	// si asta; suprascriu datele anterioare la adresa 20.&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	addr_write_tb &amp;lt;= 21;&lt;br /&gt;
	data_write_tb &amp;lt;= 11;	// scriere ok&lt;br /&gt;
	addr_read_tb &amp;lt;= 20; // citesc de la adresa 20, scrisa anteior deci voi vedea date cunoscute pe iesire.&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	addr_write_tb &amp;lt;= 23;&lt;br /&gt;
	data_write_tb &amp;lt;= 14;	// scriere ok &lt;br /&gt;
	addr_read_tb &amp;lt;= 21; // variez adresa de citire si pot parcurge memorie locatie cu locatie&lt;br /&gt;
	@(posedge clock_tb);	&lt;br /&gt;
	we_tb &amp;lt;= 0;	// opresc scrierea&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&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;
[[Fișier:Ram64X8_waveform.png|1000px]]&lt;br /&gt;
&lt;br /&gt;
In forma de unda de mai sus sunt marcate momentele de timp cand au loc scrieri in memorie (cand am write enable activ si valori cunoscute pentru data si adresa de scriere). Se salveaza valorile imediat la stanga frontului de ceas.&lt;br /&gt;
&lt;br /&gt;
In simularea completa, se poate observa si scrierea in registrii din memorie a datelor dorite  la adresa setata.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
===Exercitiul 1: RAM cu registru la iesire=== &lt;br /&gt;
&lt;br /&gt;
Pornind de la exemplul anterior, se doreste adaugarea unui registru la citirea datelor, astfel citirea devenind sincrona cu semnalul de ceas. In cod acest lucru se poate face foarte usor, punand operatia de citire pe ceas.&lt;br /&gt;
&lt;br /&gt;
Se doreste simularea si apoi testarea fizica a acestei memorii. Simularea noii memorii se face prin executarea a 3 scrieri la adrese diferite si citirea apoi a datelor respective. Sinteza si testarea fizica necesita micsorarea memoriei din cauza numarului limitat de switchuri/butoane al placii. Vom lucra acum cu o memorie de 8 locatii X 4 biti. &lt;br /&gt;
Adresa va fi comandata de switch-uri si datele de intrare din butoane. Se va folosi Button[0] pentru semnalul de &amp;quot;we&amp;quot; (write enable). Afisarea datelor se va face pe leduri.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: RAM multiport citire===&lt;br /&gt;
&lt;br /&gt;
Pornind de la exercitiul 1, se doreste modificarea memoriei astfel incat sa poata fi citite 2 locatii simultan si independent de adresa la care se face scrierea. Se pastreaza citirea sincrona.&lt;br /&gt;
&lt;br /&gt;
Se obtine astfel un circuit a carui interfata este la randul ei compusa din 3 interfete (+semnal comun &amp;quot;clock&amp;quot;): &lt;br /&gt;
&lt;br /&gt;
:- interfata de scriere &lt;br /&gt;
&lt;br /&gt;
:- interfata de citire 0&lt;br /&gt;
&lt;br /&gt;
:- interfata de citire 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Interfata circuitului arata ca in figura de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Ram_64X8_2read_1write_exterior_view.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda corespunzatoare pentru a testa aceasta memorie.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Blocul de registri (register file) din interiorul procesoarelor (vedeti AMP) poate fi o astfel de memorie RAM. Are 2 adrese pentru citirea celor 2 operanzi care intra in ALU si o adresa pentru rezultatul calculului ce este salvat.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Registrul paralel-serie===&lt;br /&gt;
&lt;br /&gt;
Descrieti comportamental un registru paralel-serie. Acesta are rolul de a salva datele de la intrare pe &amp;quot;n&amp;quot; biti (aici 8) si apoi de a le scoate la iesire bit cu bit.&lt;br /&gt;
&lt;br /&gt;
Interfata acestuia este data in desenul de mai jos. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Registru_paralel_serie.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Semnalul de &amp;quot;en&amp;quot; (enable) are rolul de a controla deplasarea, care se executa prin operatia de shiftare la dreapta &amp;quot;&amp;gt;&amp;gt;&amp;quot;. Daca acesta are valoarea &amp;quot;1&amp;quot;, datele salvate se muta la dreapta cu o pozitie.&lt;br /&gt;
:Semnalul de write_en/start/save are rolul de a salva cei 8 biti care urmeaza a fi serializati.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda corespunzatoare pentru a testa aceast circuit (minim 3 scrieri/serializari).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Bonus&amp;#039;&amp;#039;&amp;#039;: Realizati acelasi circuit folosind o descriere structurala.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Registrul serie-paralel===&lt;br /&gt;
&lt;br /&gt;
Descrieti comportamental un registru serie-paralel. Acesta are rolul de a salva date introduse bit cu bit ca apoi sa fie scoase cate &amp;quot;n&amp;quot; biti deodata.&lt;br /&gt;
&lt;br /&gt;
Interfata acestuia este data in desenul de mai jos. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Registru_serie_paralel.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
Semnalul de &amp;quot;en&amp;quot; (enable) are rolul de a controla deplasarea, care se executa prin operatia de shiftare la dreapta &amp;quot;&amp;gt;&amp;gt;&amp;quot;. Daca acesta are valoarea &amp;quot;1&amp;quot;, datele salvate se muta la dreapta cu o pozitie.&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda corespunzatoare pentru a testa aceast circuit (minim 3 scrieri/paralelizari).&lt;br /&gt;
&lt;br /&gt;
Citirea se poate face oricand, desi doar dupa &amp;quot;n&amp;quot; pasi, va fi cu valoarea corecta.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Registrul de intarziere pe 8b===&lt;br /&gt;
&lt;br /&gt;
Prin conectarea in serie a mai multor registri pe 8b (astfel incat data ce iese din unul sa fie intrare pentru urmatorul) se pot construi registri de intarziere cu &amp;quot;x&amp;quot; cicli de ceas. Cum fiecare registru salveaza datele pe ceas, se poate spune ca datele de la iesire sunt intarziate cu un ceas fata de datele de la intrare, astfel o intarziere cu &amp;quot;x&amp;quot; cicli de ceas se obtine prin punerea in serie a &amp;quot;x&amp;quot; registri. &lt;br /&gt;
&lt;br /&gt;
Pornind de la un registru simplu pe 8b (exemplul 1), construiti structural un registru de intarziere cu 4 cicli de ceas. &lt;br /&gt;
&lt;br /&gt;
Testati functionarea acestuia prin simulare. Datale introduse trebuie sa iasa defazate cu 4 cicli de ceas (adica cu 4 cicli de ceas mai tarziu).&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8335</id>
		<title>CID aplicatii 5 : Exercitii cu circuite combinationale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8335"/>
		<updated>2026-04-26T17:08:31Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exercitiul 5: Sumator cu reprezentare in cifre zecimale */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostiintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 1 in anii anteriori si cateva notiuni de teorie si sintaxa ajutatoare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: Parametrizare==&lt;br /&gt;
Parametrizarea este un mod de a generaliza codul scris pentru a nu fi necesara descrierea aceluiasi modul de mai multe ori (daca circuitul isi schimba o dimensiune). &lt;br /&gt;
&lt;br /&gt;
Pentru a intelege mai clar avantajele si sintaxa urmariti urmatorul exemplu:&lt;br /&gt;
&lt;br /&gt;
Fisierul sumator.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator # // &amp;lt;= diez deoarece urmeaza lista cu parametri&lt;br /&gt;
				( // parametri &lt;br /&gt;
					parameter data_size = 4 // valoare default 4&lt;br /&gt;
					// alti parametri aici daca este nevoie, separati prin virgula&lt;br /&gt;
				)&lt;br /&gt;
				( // interfata &lt;br /&gt;
					input logic [data_size-1:0] in0, // si pot folosi parametrul &amp;quot;data_size&amp;quot; pentru dimensiunea bus-ului&lt;br /&gt;
					input logic [data_size-1:0] in1,&lt;br /&gt;
					output logic [data_size-1:0] out0&lt;br /&gt;
				);&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 + in1;				&lt;br /&gt;
				&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cand se instantiaza un modul parametrizat, se specifica valorile parametrilor astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(8)   // se genereaza un sumator pe 8b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_0&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out0)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(32)  // se genereaza un sumator pe 32b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_1&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator nume_instanta_2 // se genereaza un sumator de dimensiune default, aici 4, asa cum e scris in modulul &amp;quot;sumator&amp;quot;&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out2)&lt;br /&gt;
	);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puteti folosi parametrizarea in exercitiul 3 de mai jos. Acolo sunt 2 tipuri de multiplexoare, unul cu intrarile pe 1 bit si unul cu intrarile pe 2 biti. Poate fi scris un singur modul parametrizat care sa acopere ambele situatii.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Concatenarea==&lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara conectare a firelor sau pentru o mai buna organizare si expresivitate a codului, de multe ori este util ca fire individuale sa fie grupate impreuna sau ca un bus de mai multi biti sa fie separat in fire individuale. Acest lucru se face folosind concatenarea, prin simbolurile &amp;quot;{ }&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Un exemplu de folosire a concatenarii este oferit mai jos.&lt;br /&gt;
Un sumator pe 8b are rezultatul pe maxim 9b, in cazul in care ambele numere sunt mari. Astfel apare un bit de carry out. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator ( &lt;br /&gt;
            input logic [7:0] in0,&lt;br /&gt;
            input logic [7:0] in1,&lt;br /&gt;
            output logic [7:0] out0,&lt;br /&gt;
            output logic carry_out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign {carry_out,out0} = in0 + in1; // fac suma intre in0 si in1 iar rezultatul il pun pe cei 9b alcatuiti din: 1b carry_out si 8b out0, in ordinea asta&lt;br /&gt;
&lt;br /&gt;
endmodule       &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Se pot concatena oricat de multe semnale, puse in &amp;quot;{ }&amp;quot; si separate prin virgula. Atentie la dimensiunile firelor care se concateneaza.&lt;br /&gt;
&lt;br /&gt;
Se poate de asemenea face concatenare si la dreapta egalului, astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fir_pe_10_b = {fir_pe_3b,fir_pe_5b,fir_pe_1b,fir_pe_1b};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In exemplul anterior ultimi 2b ai &amp;quot;fir_pe_10_b&amp;quot; vor avea mereu aceeasi valoare, provenind din acelasi fir. Sintaxa SystemVerilog permite asta.&lt;br /&gt;
&lt;br /&gt;
Puteti folosii concatenarea, in exercitiul 2, la flag-ul de overflow.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Constante ca intrari in circuite==&lt;br /&gt;
In cazul in care se doreste scrierea unor constante la intrarea unor module, acestea se pun direct intre paranteze la instantiere. &lt;br /&gt;
De exemplu, pentru multiplexorul de jos din subiectul &amp;quot;alu structural&amp;quot;, intrarea &amp;quot;in3&amp;quot; este conectata la valoarea &amp;quot;1&amp;quot;. Sintaxa pentru aceasta este: &amp;quot;.in3(1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: &amp;quot;_&amp;quot;==&lt;br /&gt;
Simbolul &amp;quot;_&amp;quot; (underscore) este ignorat de SystemVerilog si ajuta vizual la citirea semnalelor pe mai multi biti. De exemplu 16&amp;#039;b1010010111110000 este identic cu 16&amp;#039;b1010_0101_1111_0000, al doilea fiind totusi mai usor de citit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 0: Repararea erorilor===&lt;br /&gt;
Arhiva de mai jos contine mai multe proiecte in Vivado, fiecare avand cate o eroare de sintaxa sau de logica. In vederea aprofundari cunostiintelor voastre (si pentru lucrarea de saptamana urmatoare), incercati sa le parcurgeti si sa rezolvati toate problemele. &lt;br /&gt;
Pe langa proiecte in sine, in arhiva se afla si un fisier text cu o introducere, rezolvarile si explicatiile pentru fiecare situatie.&lt;br /&gt;
&lt;br /&gt;
[https://drive.google.com/file/d/1uOdI88CL0zUiW1hvgnU5H-K-AnNTWCLK/view?usp=sharing Arhiva_proiecte_cu_erori.zip]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: ALU - descriere comportamentala===&lt;br /&gt;
Descrieți comportamental o unitate aritmetico-logică (ALU) care are la intrare 2 numere binare de câte 8 biți și poate calcula următoarele funcții:&lt;br /&gt;
:- suma celor două numere&lt;br /&gt;
:- diferența celor două numere&lt;br /&gt;
:- operații logice bit cu bit (bitwise): SI, SAU, XOR și inversele lor&lt;br /&gt;
:- operandul din stanga trece neschimbat&lt;br /&gt;
:- operandul din dreapta trece neschimbat&lt;br /&gt;
:- numărul din stânga este deplasat la stânga cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
:- numărul din stânga este deplasat la dreapta cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
&lt;br /&gt;
Funcția executată la un anumit moment este determinată de configurația binară de pe intrarea de comandă (function).&lt;br /&gt;
&lt;br /&gt;
ALU are de asemenea intrare de carry și ieșire de carry, plus alte două ieșiri - indicatori - pentru cazurile când rezultatul este zero și când cei doi operanzi sunt egali.&lt;br /&gt;
&lt;br /&gt;
Intrarea de control va fi facuta pe 4 biti ca sa permita existenta a 16 operatii posibile. Fiecare numar de pe intrarea de control (combinatie de 0 si 1) va reprezenta o operatie din cele de mai sus. Scrierea se va face folosind un bloc &amp;quot;case&amp;quot; in functie de aceasta intrare. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: ALU - descriere structurala===&lt;br /&gt;
 &lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/8f/Subiect_big_alu.pdf subiect_alu.pdf]&lt;br /&gt;
	&lt;br /&gt;
Daca se doreste selectarea doar a anumitor biti dintr-un bus (cum se vrea din instruction) acest lucru se poate face in 2 feluri:&lt;br /&gt;
&lt;br /&gt;
a) cu fir aditional:&lt;br /&gt;
:&amp;#039;&amp;#039;wire [1:0] fir_aditional1;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;assign fir_aditional1 = instruction[11:10];&amp;#039;&amp;#039;&lt;br /&gt;
:// apoi la instantiere: &amp;#039;&amp;#039;.sel(fir_aditional1),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
b) direct in instantiere;&lt;br /&gt;
:la instantierea celor 2 mux4 din stanga, direct: &lt;br /&gt;
::&amp;#039;&amp;#039;.sel(instruction[11:10]),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie mai putin (a nu face toate modulele de calcul separat + instantierea lor) si pentru ca e vorba de operatii simple, se poate pune operatia cu assign direct in top pe un fir declarat acolo, sau si mai prescurtat, direct operatia dorita cand se intantiaza modulul in care aceasta intra. De exemplu, pentru operatia de shift la dreapta care intra in primul multiplexor, se poate pune:  &amp;quot;.in0(data0 &amp;gt;&amp;gt; data1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Multiplexoare===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/3/3a/Subiect_muxes.pdf subiect_muxes.pdf]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Rom/Look-up table===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2e/Subiect_rom_luts.pdf rom_luts.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Sumator cu reprezentare in cifre zecimale===&lt;br /&gt;
Proiectati si verificati un sumator zecimal pentru numere cu 2 cifre&lt;br /&gt;
&lt;br /&gt;
Modulul de top (Figura 1) este alcatuit din 2 blocuri de tip &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;. Fiecare bloc aduna cifrele de pe aceasi pozitie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 1&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
   Top level&lt;br /&gt;
&lt;br /&gt;
[[Fișier: bcdsum.png]]&lt;br /&gt;
&lt;br /&gt;
Blocul &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; (Figura 2) este alcatuit din 4 blocuri, 2 sumatoare binare pe 4 biti (de tip &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039;), o instanta de &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039; si un multiplexor elementar mux2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 2&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
   Blocul DIGIT SUM &lt;br /&gt;
&lt;br /&gt;
[[Fișier: digit.png]]&lt;br /&gt;
&lt;br /&gt;
Primul sumator aduna cifrele din domeniul [0...9] avand un rezultat intre [0 ... 18] &lt;br /&gt;
&lt;br /&gt;
Comparatorul are la iesire 1 daca rezultatul este mai mare decat 9.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mic decat 9, acesta este trimis in mod direct la iesirea &amp;#039;&amp;#039;&amp;#039;digit&amp;#039;&amp;#039;&amp;#039; a blocului &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mare decat 9, o corectie este necesara si se aduna 6 la rezultat.&lt;br /&gt;
&lt;br /&gt;
Comparatorul cu valoarea 9 este descris structural din porti in figura de mai jos: &lt;br /&gt;
&lt;br /&gt;
Atentie: In acest comparator, intrarea pentru bitul [0] se ignora.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 3&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
   the comparator &lt;br /&gt;
&lt;br /&gt;
[[Fișier: cmp.png]]&lt;br /&gt;
&lt;br /&gt;
Testbench-ul va genera stimuli pentru &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
Intrarea b0 a &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; se schimba la fiecare 5 pasi de simulare .&lt;br /&gt;
&lt;br /&gt;
b1, a0 si a1 se schimba sincron cu b0 ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: teststimuli.png]]&lt;br /&gt;
&lt;br /&gt;
Cerinte:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039;- descris structural la nivel de porti ca in Figura 3.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039; descris comportamental cu un assign continuu.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;mux&amp;#039;&amp;#039;&amp;#039; descris comportamental cu always.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; descris strctural ca in Figura 2.&lt;br /&gt;
# modulul de top numit &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039;, descris structural ca in Figure 1.&lt;br /&gt;
# modulul de testbench, &amp;#039;&amp;#039;&amp;#039;bcdsum_tb&amp;#039;&amp;#039;&amp;#039;, instantiaza &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; cu numele &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# in testbench, generati stimuli pentru intrarile circuitului testat.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Codor Cezar===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/9/92/Cid_L1_codor_Cezar.pdf Codor_Cezar.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 7: Calcul si Flag-uri===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/c/c2/L1_calcul_si_flaguri.pdf Calcul_si_flaguri.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 8: Unitate aritmetico-logică (ALU)===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/85/Subiect_ALU_pentru_wiki.pdf Unitate_aritmetico-logica]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8334</id>
		<title>CID aplicatii 5 : Exercitii cu circuite combinationale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8334"/>
		<updated>2026-04-26T16:25:02Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exercitiul 5: Sumator cu reprezentare in cifre zecimale */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostiintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 1 in anii anteriori si cateva notiuni de teorie si sintaxa ajutatoare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: Parametrizare==&lt;br /&gt;
Parametrizarea este un mod de a generaliza codul scris pentru a nu fi necesara descrierea aceluiasi modul de mai multe ori (daca circuitul isi schimba o dimensiune). &lt;br /&gt;
&lt;br /&gt;
Pentru a intelege mai clar avantajele si sintaxa urmariti urmatorul exemplu:&lt;br /&gt;
&lt;br /&gt;
Fisierul sumator.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator # // &amp;lt;= diez deoarece urmeaza lista cu parametri&lt;br /&gt;
				( // parametri &lt;br /&gt;
					parameter data_size = 4 // valoare default 4&lt;br /&gt;
					// alti parametri aici daca este nevoie, separati prin virgula&lt;br /&gt;
				)&lt;br /&gt;
				( // interfata &lt;br /&gt;
					input logic [data_size-1:0] in0, // si pot folosi parametrul &amp;quot;data_size&amp;quot; pentru dimensiunea bus-ului&lt;br /&gt;
					input logic [data_size-1:0] in1,&lt;br /&gt;
					output logic [data_size-1:0] out0&lt;br /&gt;
				);&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 + in1;				&lt;br /&gt;
				&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cand se instantiaza un modul parametrizat, se specifica valorile parametrilor astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(8)   // se genereaza un sumator pe 8b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_0&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out0)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(32)  // se genereaza un sumator pe 32b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_1&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator nume_instanta_2 // se genereaza un sumator de dimensiune default, aici 4, asa cum e scris in modulul &amp;quot;sumator&amp;quot;&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out2)&lt;br /&gt;
	);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puteti folosi parametrizarea in exercitiul 3 de mai jos. Acolo sunt 2 tipuri de multiplexoare, unul cu intrarile pe 1 bit si unul cu intrarile pe 2 biti. Poate fi scris un singur modul parametrizat care sa acopere ambele situatii.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Concatenarea==&lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara conectare a firelor sau pentru o mai buna organizare si expresivitate a codului, de multe ori este util ca fire individuale sa fie grupate impreuna sau ca un bus de mai multi biti sa fie separat in fire individuale. Acest lucru se face folosind concatenarea, prin simbolurile &amp;quot;{ }&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Un exemplu de folosire a concatenarii este oferit mai jos.&lt;br /&gt;
Un sumator pe 8b are rezultatul pe maxim 9b, in cazul in care ambele numere sunt mari. Astfel apare un bit de carry out. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator ( &lt;br /&gt;
            input logic [7:0] in0,&lt;br /&gt;
            input logic [7:0] in1,&lt;br /&gt;
            output logic [7:0] out0,&lt;br /&gt;
            output logic carry_out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign {carry_out,out0} = in0 + in1; // fac suma intre in0 si in1 iar rezultatul il pun pe cei 9b alcatuiti din: 1b carry_out si 8b out0, in ordinea asta&lt;br /&gt;
&lt;br /&gt;
endmodule       &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Se pot concatena oricat de multe semnale, puse in &amp;quot;{ }&amp;quot; si separate prin virgula. Atentie la dimensiunile firelor care se concateneaza.&lt;br /&gt;
&lt;br /&gt;
Se poate de asemenea face concatenare si la dreapta egalului, astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fir_pe_10_b = {fir_pe_3b,fir_pe_5b,fir_pe_1b,fir_pe_1b};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In exemplul anterior ultimi 2b ai &amp;quot;fir_pe_10_b&amp;quot; vor avea mereu aceeasi valoare, provenind din acelasi fir. Sintaxa SystemVerilog permite asta.&lt;br /&gt;
&lt;br /&gt;
Puteti folosii concatenarea, in exercitiul 2, la flag-ul de overflow.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Constante ca intrari in circuite==&lt;br /&gt;
In cazul in care se doreste scrierea unor constante la intrarea unor module, acestea se pun direct intre paranteze la instantiere. &lt;br /&gt;
De exemplu, pentru multiplexorul de jos din subiectul &amp;quot;alu structural&amp;quot;, intrarea &amp;quot;in3&amp;quot; este conectata la valoarea &amp;quot;1&amp;quot;. Sintaxa pentru aceasta este: &amp;quot;.in3(1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: &amp;quot;_&amp;quot;==&lt;br /&gt;
Simbolul &amp;quot;_&amp;quot; (underscore) este ignorat de SystemVerilog si ajuta vizual la citirea semnalelor pe mai multi biti. De exemplu 16&amp;#039;b1010010111110000 este identic cu 16&amp;#039;b1010_0101_1111_0000, al doilea fiind totusi mai usor de citit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 0: Repararea erorilor===&lt;br /&gt;
Arhiva de mai jos contine mai multe proiecte in Vivado, fiecare avand cate o eroare de sintaxa sau de logica. In vederea aprofundari cunostiintelor voastre (si pentru lucrarea de saptamana urmatoare), incercati sa le parcurgeti si sa rezolvati toate problemele. &lt;br /&gt;
Pe langa proiecte in sine, in arhiva se afla si un fisier text cu o introducere, rezolvarile si explicatiile pentru fiecare situatie.&lt;br /&gt;
&lt;br /&gt;
[https://drive.google.com/file/d/1uOdI88CL0zUiW1hvgnU5H-K-AnNTWCLK/view?usp=sharing Arhiva_proiecte_cu_erori.zip]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: ALU - descriere comportamentala===&lt;br /&gt;
Descrieți comportamental o unitate aritmetico-logică (ALU) care are la intrare 2 numere binare de câte 8 biți și poate calcula următoarele funcții:&lt;br /&gt;
:- suma celor două numere&lt;br /&gt;
:- diferența celor două numere&lt;br /&gt;
:- operații logice bit cu bit (bitwise): SI, SAU, XOR și inversele lor&lt;br /&gt;
:- operandul din stanga trece neschimbat&lt;br /&gt;
:- operandul din dreapta trece neschimbat&lt;br /&gt;
:- numărul din stânga este deplasat la stânga cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
:- numărul din stânga este deplasat la dreapta cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
&lt;br /&gt;
Funcția executată la un anumit moment este determinată de configurația binară de pe intrarea de comandă (function).&lt;br /&gt;
&lt;br /&gt;
ALU are de asemenea intrare de carry și ieșire de carry, plus alte două ieșiri - indicatori - pentru cazurile când rezultatul este zero și când cei doi operanzi sunt egali.&lt;br /&gt;
&lt;br /&gt;
Intrarea de control va fi facuta pe 4 biti ca sa permita existenta a 16 operatii posibile. Fiecare numar de pe intrarea de control (combinatie de 0 si 1) va reprezenta o operatie din cele de mai sus. Scrierea se va face folosind un bloc &amp;quot;case&amp;quot; in functie de aceasta intrare. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: ALU - descriere structurala===&lt;br /&gt;
 &lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/8f/Subiect_big_alu.pdf subiect_alu.pdf]&lt;br /&gt;
	&lt;br /&gt;
Daca se doreste selectarea doar a anumitor biti dintr-un bus (cum se vrea din instruction) acest lucru se poate face in 2 feluri:&lt;br /&gt;
&lt;br /&gt;
a) cu fir aditional:&lt;br /&gt;
:&amp;#039;&amp;#039;wire [1:0] fir_aditional1;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;assign fir_aditional1 = instruction[11:10];&amp;#039;&amp;#039;&lt;br /&gt;
:// apoi la instantiere: &amp;#039;&amp;#039;.sel(fir_aditional1),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
b) direct in instantiere;&lt;br /&gt;
:la instantierea celor 2 mux4 din stanga, direct: &lt;br /&gt;
::&amp;#039;&amp;#039;.sel(instruction[11:10]),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie mai putin (a nu face toate modulele de calcul separat + instantierea lor) si pentru ca e vorba de operatii simple, se poate pune operatia cu assign direct in top pe un fir declarat acolo, sau si mai prescurtat, direct operatia dorita cand se intantiaza modulul in care aceasta intra. De exemplu, pentru operatia de shift la dreapta care intra in primul multiplexor, se poate pune:  &amp;quot;.in0(data0 &amp;gt;&amp;gt; data1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Multiplexoare===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/3/3a/Subiect_muxes.pdf subiect_muxes.pdf]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Rom/Look-up table===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2e/Subiect_rom_luts.pdf rom_luts.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Sumator cu reprezentare in cifre zecimale===&lt;br /&gt;
Proiectati si verificati un sumator zecimal pentru numere cu 2 cifre&lt;br /&gt;
&lt;br /&gt;
Modulul de top (Figura 1) este alcatuit din 2 blocuri de tip &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;. Fiecare bloc aduna cifrele de pe aceasi pozitie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 1&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
   Top level&lt;br /&gt;
&lt;br /&gt;
[[Fișier: bcdsum.png]]&lt;br /&gt;
&lt;br /&gt;
Blocul &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; (Figura 2) este alcatuit din 4 blocuri, 2 sumatoare binare pe 4 biti (de tip &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039;), o instanta de &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039; si un multiplexor elementar mux2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 2&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
   Blocul DIGIT SUM &lt;br /&gt;
&lt;br /&gt;
[[Fișier: digit.png]]&lt;br /&gt;
&lt;br /&gt;
Primul sumator aduna cifrele din domeniul [0...9] avand un rezultat intre [0 ... 18] &lt;br /&gt;
&lt;br /&gt;
Comparatorul are la iesire 1 daca rezultatul este mai mare decat 9.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mic decat 9, acesta este trimis in mod direct la iesirea &amp;#039;&amp;#039;&amp;#039;digit&amp;#039;&amp;#039;&amp;#039; a blocului &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mare decat 9, o corectie este necesara si se aduna 6 la rezultat.&lt;br /&gt;
&lt;br /&gt;
Comparatorul cu valoarea 9 este descris structural din porti in figura de mai jos: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 3&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
   the comparator &lt;br /&gt;
&lt;br /&gt;
[[Fișier: cmp.png]]&lt;br /&gt;
&lt;br /&gt;
Testbench-ul va genera stimuli pentru &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
Intrarea b0 a &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; se schimba la fiecare 5 pasi de simulare .&lt;br /&gt;
&lt;br /&gt;
b1, a0 si a1 se schimba sincron cu b0 ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: teststimuli.png]]&lt;br /&gt;
&lt;br /&gt;
Cerinte:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039;- descris structural la nivel de porti ca in Figura 3.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039; descris comportamental cu un assign continuu.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;mux&amp;#039;&amp;#039;&amp;#039; descris comportamental cu always.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; descris strctural ca in Figura 2.&lt;br /&gt;
# modulul de top numit &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039;, descris structural ca in Figure 1.&lt;br /&gt;
# modulul de testbench, &amp;#039;&amp;#039;&amp;#039;bcdsum_tb&amp;#039;&amp;#039;&amp;#039;, instantiaza &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; cu numele &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# in testbench, generati stimuli pentru intrarile circuitului testat.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Codor Cezar===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/9/92/Cid_L1_codor_Cezar.pdf Codor_Cezar.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 7: Calcul si Flag-uri===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/c/c2/L1_calcul_si_flaguri.pdf Calcul_si_flaguri.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 8: Unitate aritmetico-logică (ALU)===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/85/Subiect_ALU_pentru_wiki.pdf Unitate_aritmetico-logica]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_10_:_Aplicatii_cu_numaratoare&amp;diff=8333</id>
		<title>CID aplicatii 10 : Aplicatii cu numaratoare</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_10_:_Aplicatii_cu_numaratoare&amp;diff=8333"/>
		<updated>2026-04-23T10:57:29Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exemplu: Numaratul apasarilor unui buton */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Teorie==&lt;br /&gt;
&lt;br /&gt;
Numaratoarele au extrem de multe aplicatii in lumea reala, cateva dintre acestea fiind descrise mai jos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exemplu: Numaratul apasarilor unui buton==&lt;br /&gt;
	&lt;br /&gt;
Un prim sistem simplu cu numarator poate fi cel care contorizeaza de cate ori a fost apasat un buton sau, echivalent, cate persoane/masini au trecut printr-un senzor, de cate ori a fost deschisa o usa etc. Acest sistem se poate apoi dezvolta cu usurinta pentru a numara si oamenii care trec invers prin respectivul set de senzori prin adaugarea functionalitatii de up/down la numarator.&lt;br /&gt;
&lt;br /&gt;
Un astfel de sistem simplu (varianta doar cu numarat intrari) ar arata in felul urmator: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Aplicatii_numarator_exemplu_contor_senzor.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
Circuitul de debounce are rolul de a &amp;quot;curata&amp;quot; semnalul de intrare, astfel incat chiar si in prezenta zgomotului sau a unei activari indelungate a senzorului/butonului, sa se contorizeze un singur eveniment. O explicatie mai detaliata puteti gasi [[Circuitul_de_debounce|aici]].&lt;br /&gt;
&lt;br /&gt;
Numaratorul numara evenimentele.&lt;br /&gt;
&lt;br /&gt;
Transcodorul pentru display cu 7 segmente este apoi folosit pentru o mai usoara vizualizare a numarului curent. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; transcodorul pentru 7seg din exemplul de mai jos este in logica negativa. Daca circuitul fizic este in logica pozitiva trebuie adaugat un inversor la iesirea din acesta. De asemnea consider segmentul &amp;quot;a&amp;quot; pe bitul &amp;quot;0&amp;quot; si segmentul &amp;quot;h&amp;quot; pe bitul &amp;quot;6&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea debouncer-ului (fisierul debounce.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module debounce&lt;br /&gt;
	#(&lt;br /&gt;
		parameter limit = 20&amp;#039;d650000&lt;br /&gt;
	) (&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic in,&lt;br /&gt;
		output logic out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
logic [19:0] counter; // observatie: si circuitul de debounce foloseste un numarator&lt;br /&gt;
logic hit;&lt;br /&gt;
&lt;br /&gt;
assign out = (counter == limit);&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) &lt;br /&gt;
begin&lt;br /&gt;
	if(in == 0) &lt;br /&gt;
		begin&lt;br /&gt;
		counter &amp;lt;= 0;&lt;br /&gt;
		hit &amp;lt;= 0;        &lt;br /&gt;
		end &lt;br /&gt;
	else &lt;br /&gt;
		begin&lt;br /&gt;
		if(counter == limit) &lt;br /&gt;
			begin&lt;br /&gt;
			hit &amp;lt;= 1;&lt;br /&gt;
			counter &amp;lt;= counter + 1;&lt;br /&gt;
			end &lt;br /&gt;
		else &lt;br /&gt;
			begin&lt;br /&gt;
			if(in == 1 &amp;amp; hit == 0) &lt;br /&gt;
				begin&lt;br /&gt;
				counter &amp;lt;= counter + 1;&lt;br /&gt;
				end&lt;br /&gt;
			end&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;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea numaratorului pe 4b(fisierul counter_4b.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module counter_4b&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset,&lt;br /&gt;
		input logic en,&lt;br /&gt;
		output logic [3:0] out&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
always_ff @(posedge clock)&lt;br /&gt;
begin&lt;br /&gt;
	if(reset == 1)&lt;br /&gt;
		begin&lt;br /&gt;
		out &amp;lt;=0;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		begin&lt;br /&gt;
		if(en == 1)&lt;br /&gt;
			begin&lt;br /&gt;
			out &amp;lt;= out + 1;&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			begin&lt;br /&gt;
			out &amp;lt;= out;&lt;br /&gt;
			end&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;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea transcodorului pentru afisaj cu 7seg(fisierul transcodor_7seg.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module transcodor_7seg				// logica negativa &lt;br /&gt;
	(&lt;br /&gt;
		input logic [3:0] in,&lt;br /&gt;
  		output logic [6:0] out&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
always_comb&lt;br /&gt;
begin&lt;br /&gt;
	case(in)&lt;br /&gt;
		4&amp;#039;d0: out = 7&amp;#039;b1000000;// h....a&lt;br /&gt;
		4&amp;#039;d1: out = 7&amp;#039;b1111001;&lt;br /&gt;
		4&amp;#039;d2: out = 7&amp;#039;b0100100;&lt;br /&gt;
		4&amp;#039;d3: out = 7&amp;#039;b0110000;&lt;br /&gt;
		4&amp;#039;d4: out = 7&amp;#039;b0011001;&lt;br /&gt;
		4&amp;#039;d5: out = 7&amp;#039;b0010010;&lt;br /&gt;
		4&amp;#039;d6: out = 7&amp;#039;b0000010;&lt;br /&gt;
		4&amp;#039;d7: out = 7&amp;#039;b1111000;&lt;br /&gt;
		4&amp;#039;d8: out = 7&amp;#039;b0000000;&lt;br /&gt;
		4&amp;#039;d9: out = 7&amp;#039;b0010000;&lt;br /&gt;
		4&amp;#039;d10: out = 7&amp;#039;b0001000;&lt;br /&gt;
		4&amp;#039;d11: out = 7&amp;#039;b0000011;&lt;br /&gt;
		4&amp;#039;d12: out = 7&amp;#039;b1000110;&lt;br /&gt;
		4&amp;#039;d13: out = 7&amp;#039;b0100001;&lt;br /&gt;
		4&amp;#039;d14: out = 7&amp;#039;b0000110;&lt;br /&gt;
		4&amp;#039;d15: out = 7&amp;#039;b0001110;&lt;br /&gt;
		default: out = 7&amp;#039;b1111111;//tot stins &lt;br /&gt;
	endcase &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;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea sistemului, modulul de top (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset,&lt;br /&gt;
		input logic button,&lt;br /&gt;
		output logic [6:0] out    // logica negativa &lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic debounce_0_X_out;&lt;br /&gt;
logic [3:0] counter_4b_0_X_out;   &lt;br /&gt;
    &lt;br /&gt;
debounce&lt;br /&gt;
	#(&lt;br /&gt;
		.limit(20&amp;#039;d50_000)&lt;br /&gt;
	) debounce_0 (&lt;br /&gt;
		.clock(clock),&lt;br /&gt;
		.in(button),&lt;br /&gt;
		.out(debounce_0_X_out)&lt;br /&gt;
	);&lt;br /&gt;
	    &lt;br /&gt;
counter_4b counter_4b_0&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock),&lt;br /&gt;
		.reset(reset),&lt;br /&gt;
		.en(debounce_0_X_out),&lt;br /&gt;
		.out(counter_4b_0_X_out)&lt;br /&gt;
    );    &lt;br /&gt;
    &lt;br /&gt;
transcodor_7seg	transcodor_7seg_0			// logica negativa &lt;br /&gt;
	(&lt;br /&gt;
		.in(counter_4b_0_X_out),&lt;br /&gt;
  		.out(out)&lt;br /&gt;
    );    &lt;br /&gt;
 &lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea test bench-ului(fisierul tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module tb();&lt;br /&gt;
&lt;br /&gt;
logic clock_tb;&lt;br /&gt;
logic reset_tb;&lt;br /&gt;
logic button_tb;&lt;br /&gt;
logic [6:0] out_tb;&lt;br /&gt;
&lt;br /&gt;
top dut&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock_tb),&lt;br /&gt;
		.reset(reset_tb),&lt;br /&gt;
		.button(button_tb),&lt;br /&gt;
		.out(out_tb)    // logica negativa &lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	clock_tb = 0;&lt;br /&gt;
	forever&lt;br /&gt;
		begin&lt;br /&gt;
		#5 clock_tb = ~clock_tb;&lt;br /&gt;
		end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	reset_tb &amp;lt;= 0;&lt;br /&gt;
	button_tb &amp;lt;= 0;&lt;br /&gt;
	&lt;br /&gt;
	#50;&lt;br /&gt;
	reset_tb &amp;lt;= 1;&lt;br /&gt;
	#50;&lt;br /&gt;
	reset_tb &amp;lt;= 0;&lt;br /&gt;
	#100;&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) 	// vreau 5 apasari de buton&lt;br /&gt;
		begin&lt;br /&gt;
		button_tb &amp;lt;= 1;&lt;br /&gt;
		repeat(70_000)				&lt;br /&gt;
			begin&lt;br /&gt;
			@(posedge clock_tb);&lt;br /&gt;
			end&lt;br /&gt;
		button_tb &amp;lt;= 0;&lt;br /&gt;
		repeat(70_000)&lt;br /&gt;
			begin&lt;br /&gt;
			@(posedge clock_tb);&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
	#1000 $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;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
=== Exercitiul 1: Divizor de frecventa cu puteri ale lui 2=== &lt;br /&gt;
&lt;br /&gt;
Divizorul de frecventa are rolul de a genera un semnal de ceas mai lent din semnalul de ceas principal. &lt;br /&gt;
El este alcatuit doar dintr-un numarator, iar fiecare bit al acestuia va fi practic un semnal de ceas cu frecventa din ce in ce mai mica astfel (la jumate): &lt;br /&gt;
&lt;br /&gt;
bit[0] - frecventa de 2 ori mai mica decat semnalul de ceas&lt;br /&gt;
 &lt;br /&gt;
bit[1] - frecventa de 2 ori mai mica decat bit[0], deci de 4 ori mai mica decat semnalul de ceas &lt;br /&gt;
&lt;br /&gt;
bit[2] - frecventa de 2 ori mai mica decat bit[1], deci de 8 ori mai mica decat semnalul de ceas &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Acest lucru se poate observa si in poza ce urmeaza: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Freq_divider_output.png| 800px]] &lt;br /&gt;
&lt;br /&gt;
Implementati acest circuit, si folosind ledurile prezente pe placa, incercati sa conectati bitul corespunzator la leduri astfel incat cel mai din dreapta led sa clipeasca cu o frecventa cat mai apropiata de 1s. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Printr-un astfel de divizor de frecventa minimal, un numar foarte mic de frecvente poate fi generat. Daca se doreste generarea unui semnal periodic cu o perioada exacta, diferita de cele posibile prin acest mecanism, se poate construi urmatorul circuit:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: Divizor de frecventa ce poate genera orice perioada=== &lt;br /&gt;
&lt;br /&gt;
Un astfel de divizor de frecventa este construit ca in figura de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Freq_div_orice_freq.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
Prin adaugarea constantei &amp;quot;limit&amp;quot;, perioada semnalului de iesire poate sa fie orice multiplu a perioadei semnalului de ceas. &lt;br /&gt;
&lt;br /&gt;
Bistabilul de tip t, se modifica atunci cand limita este atinsa si practic iesirea lui este semnalul periodic dorit (cu observatia ca o perioada a semnalului de iesire necesita 2 numarari pana la limita).&lt;br /&gt;
&lt;br /&gt;
Sa se calculeze valoarea necesara pentru &amp;quot;limit&amp;quot; astfel incat pe leduri sa se genereze semnal cu perioada exact 1s.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; In FPGA exista fizic trasee speciale pentru reset si ca sinteza sa le foloseasca pe acestea in mod optim nu este recomandat sa se puna logica (cum e aici poarta sau) pe acestea. Modificati schema de mai sus astfel incat sa eliminati respectiva poarta de pe reset. (Sfat: numaratorul va avea acum si intrari de load: semnalul de comanda si data propriu zisa)&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: PWM (Pulse Width Modulation)===&lt;br /&gt;
&lt;br /&gt;
PWM este un concept folosit foarte des in multiple ramuri ale ingineriei, de la transmisiunea informatiei pana la controlul motoarelor sau al intensitatii ledurilor din instalatii de Craciun. El se refera la a avea un semnal periodic cu factor de umplere variabil, asa cum este aratat in poza de mai jos :&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm.png| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generarea unui astfel de semnal periodic se face printr-un numarator si un comparator, ca in figura de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm_schematic.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raportul dintre limita pusa si valoarea la care numaratorul se reseteaza este practic factorul de umplere selectat.&lt;br /&gt;
&lt;br /&gt;
Pentru testare pe placa, cei 6b ai limitei provin de la switch-uri si butoane. Afisarea se face pe led[0].&lt;br /&gt;
&lt;br /&gt;
Testati acest circuit in simulare si apoi implementati pe placa pentru o valoare fixa a limitei. Implementati in paralel mai multe generatoare de semnal PWM cu limite diferite, astfel incat sa observati diferentele de intentistate dintre ledurile comandate de acestea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: PWM cu limita variabila===&lt;br /&gt;
&lt;br /&gt;
Un exemplu foarte uzual de folosire a PWM este aprinderea ledurilor cu diverse pattern-uri. Factorul de umplere determina intensitatea cu care ledul este aprins. Un PWM cu o limita variabila automata va face ledul sa para din ce in ce mai stins sau din ce in ce mai luminos (exemplu: instalatii de Craciun). Combinand asta cu leduri RGB se obtin efecte de schimbare a culorii ledului aparent la intamplare. &lt;br /&gt;
&lt;br /&gt;
Un astfel de circuit se realizeaza punand inca un numarator in locul limitei, ca in poza de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm_duty_cycle_up_schematic.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru o functionalitate suplimentara, anume a pastra un anumit factor de umplere mai multe perioade, am adaugat inca un numarator.&lt;br /&gt;
&lt;br /&gt;
Pentru claritatea desenului, nu am mai tras efectiv firul de ceas catre intrarile unde acesta se duce.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rezultatul este: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm_duty_cycle_up_output.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Testati circuitul propus prin simulare si apoi vizualizati implementarea sa pe placa. Alegeti limite potrivite astfel incat sa puteti observa usor rezultatul.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Bonus:&amp;#039;&amp;#039;&amp;#039; Incercati sa adaugati si parametri pentru LIMIT_DUTY_CYCLE_LOW si LIMIT_DUTY_CYCLE_HIGH, care sa permita factorului de umplere sa varieze doar intre ele (numaratorul va avea nevoie de intrari pentru comanda de load si data load, ca sa poata incepe de la orice valoare).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Bonus:&amp;#039;&amp;#039;&amp;#039; Modificati circuitul astfel incat semnalul de iesire sa isi schimbe sensul de variatie al factorului de umplere cand ajunge cu acesta la capat. In forma curenta factorul de umplere creste de la 0% la 100% si apoi se reseteaza brusc la 0%, repetand acest ciclu. Se vrea ca la ajungerea la 100% sa inceapa o scadere treptata catre 0%, urmata apoi de o urcare s.a.m.d.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Ceas===&lt;br /&gt;
&lt;br /&gt;
Un ceas poate fi construit cifra cu cifra, folosind numaratoare si comparatoare (si transcodoare pentru display cu 7seg ca sa se vada totul mai bine pe placa).&lt;br /&gt;
&lt;br /&gt;
Incercati sa implementati un ceas cu milisecunde, secunde si minute in varianta comportamentala. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Va fi nevoie fie separat, fie in modul de un numarator cu frecventa rezolutiei dorite (aici 1 ms).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Codul va contine multe &amp;quot;if&amp;quot; de tipul &amp;quot;daca cifra unitatilor secundelor a ajuns la 10, se face 0 si cresc cifra zecilor&amp;quot;, repetate pentru fiecare cifra.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Incercati si o implementare structurala a ceasului, mergand pe aceeasi idee. Fiecare cifra va contine numaratorul ei. Cand numaratorul unei cifre ajunge ajunge la limita sa, va da enable pentru numaratorul cifrei urmatoare. Daca este nevoie se pot folosi si porti aditionale (ex: ca sa creasca minutul cifra zecilor secundelor trebuie sa fie 5 si cifra unitatilor secundelor trebuie sa fie 9). &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Va fi nevoie de un numarator cu frecventa rezolutiei dorite (aici 1 ms sau 1s).&lt;br /&gt;
 &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Pentru a scrie mai putin puteti face un numarator doar cu secunde si minute. Principiul de baza este acelasi si daca aveati milisecunde.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Simularea a cateva milisecunde sau chiar secunde este un proces indelungat (dureaza minute-ore fizice), astfel strict pentru simulari se recomanda ceasul sa functioneze cu microsecunde sau milisecunde maxim.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_9_:_Numaratorul&amp;diff=8332</id>
		<title>CID aplicatii 9 : Numaratorul</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_9_:_Numaratorul&amp;diff=8332"/>
		<updated>2026-04-23T10:56:47Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exemple */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Numărătorul ==&lt;br /&gt;
Numărătorul este cel mai simplu automat, fiind format dintr-un registru (element de memorare) ce reține valoarea curentă a acestuia și un circuit de incrementare (circuit de reacție) ce generează la ieșirea sa valoarea ce va trebui stocată în registru la următorul front crescător de ceas (valoarea curentă incrementată cu 1). &lt;br /&gt;
&lt;br /&gt;
În figura de mai jos este reprezentat un numărător cu reset sincron:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Numarator cu reset.png|600px]]&lt;br /&gt;
&lt;br /&gt;
În cazul de mai sus, cât timp semnalul &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; este activ, valoarea numărătorului va fi 0. Atunci când semnalul &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; nu este activ, numărătorul își va incrementa valoarea la fiecare front crescător de ceas.&lt;br /&gt;
&lt;br /&gt;
== Divizor de frecvență cu factor de divizare putere a lui 2==&lt;br /&gt;
În unele cazuri, apare necesitatea obținerii unor semnale de ceas cu frecvență mai mică decât cea a ceasului de sistem. Aceste noi semnale de ceas pot fi obținute chiar din semnalul de ceas al sistemului, prin circuite care realizează divizarea acestuia. Cea mai simplă divizare a unui semnal de ceas este cea cu factor de divizare egal cu o putere a lui 2. Pentru acest caz, putem folosi un numărător.&lt;br /&gt;
&lt;br /&gt;
Dacă urmărim figura de mai jos în care sunt reprezentate variațiile fiecărui bit în timpul funcționării unui numărător pe 4 biți, observăm că, cu cât ordinul bitului crește (este mai semnificativ), frecvența de variație este mai mică. Între frecvențele de variație corespunzătoare a doi biți succesivi există următoarea relație: frecvența unui bit este de două ori mai mică decât frecvența bitului anterior (mai puțin semnificativ).&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Divizare frecventa.png]]&lt;br /&gt;
&lt;br /&gt;
Observând că frecvența bitului 0 este de două ori mai mică decât cea a ceasului, putem concluziona că frecvența de variație a bitului cu indicele N este dată de: &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;f&amp;lt;sub&amp;gt;bN&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039; = &amp;#039;&amp;#039;f&amp;lt;sub&amp;gt;clk&amp;lt;/sub&amp;gt; / 2&amp;lt;sup&amp;gt;N+1&amp;lt;/sup&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Așadar, pentru a realiza un divizor de frecvență cu factor de divizare putere a lui 2, putem folosi un numărător îndeajuns de mare, din care extragem bitul cu frecvența de variație egală cu frecvența dorită.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exemple==&lt;br /&gt;
===Exemplul 1: Implementarea unui numărător cu reset sincron===&lt;br /&gt;
În acest exemplu vom realiza implementarea numărătorului cu reset sincron prezentat în figura din secțiunea de introducere teoretică. În plus, vom folosi parametrul WIDTH pentru a controla dimensiunea acestuia.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea Numărătorului cu reset sincron&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module Numarator&lt;br /&gt;
#(parameter WIDTH = 8)&lt;br /&gt;
(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic reset_n,&lt;br /&gt;
    output logic [WIDTH-1:0] count  &lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset_n == 0)&lt;br /&gt;
        count &amp;lt;= 0;&lt;br /&gt;
    else&lt;br /&gt;
        count &amp;lt;= count + 1;  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru numărător&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps&lt;br /&gt;
&lt;br /&gt;
module Numarator_TB();&lt;br /&gt;
&lt;br /&gt;
parameter WIDTH_T = 5;&lt;br /&gt;
logic reset_n_t, clock_t;&lt;br /&gt;
logic [WIDTH_T-1:0] count_t;&lt;br /&gt;
	&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
	&lt;br /&gt;
initial begin&lt;br /&gt;
        reset_n_t &amp;lt;= 0;&lt;br /&gt;
    #2 	reset_n_t &amp;lt;= 1;&lt;br /&gt;
    #500 $stop();	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
Numarator #(.WIDTH(WIDTH_T)) DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset_n(reset_n_t),&lt;br /&gt;
    .count(count_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Cât timp semnalul &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; este inactiv, numărătorul își va incrementa valoarea la fiecare front crescător de ceas. Când va ajunge la valoarea sa maximă (de exemplu, 31 pentru un numărător pe 5 biți), va avea loc o depășire și având la dispozitie un număr limitat de biți (de exemplu, 5), semnalul de ieșire va deveni 0 (reținem doar cei mai puțin semnificativi 5 biți), circuitul reluând numărarea de la capat.&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Observarea vitezei de variație a biților unui numărător===&lt;br /&gt;
În acest exemplu vom realiza implementarea unui divizor de frecvență ce generează la ieșire 4 semnale de ceas cu următoarele frecvențe:&lt;br /&gt;
* &amp;#039;&amp;#039;clkout1&amp;#039;&amp;#039;: semnal de ceas cu frecvența de 1 Hz.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout2&amp;#039;&amp;#039;: semnal de ceas cu frecvența de 2 Hz.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout4&amp;#039;&amp;#039;: semnal de ceas cu frecvența de 4 Hz.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout8&amp;#039;&amp;#039;: semnal de ceas cu frecvența de 8 Hz.&lt;br /&gt;
&lt;br /&gt;
Dacă aplicăm formula &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;f&amp;lt;sub&amp;gt;bN&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039; = &amp;#039;&amp;#039;f&amp;lt;sub&amp;gt;clk&amp;lt;/sub&amp;gt; / 2&amp;lt;sup&amp;gt;N+1&amp;lt;/sup&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; cunoscând că frecvența de ceas a FPGA-ului este de 100 MHz, vom obține:&lt;br /&gt;
* &amp;#039;&amp;#039;clkout1&amp;#039;&amp;#039; poate fi obținut prin bitul 26 al unui numărător.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout2&amp;#039;&amp;#039; poate fi obținut prin bitul 25 al unui numărător.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout4&amp;#039;&amp;#039; poate fi obținut prin bitul 24 al unui numărător.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout8&amp;#039;&amp;#039; poate fi obținut prin bitul 23 al unui numărător.&lt;br /&gt;
&lt;br /&gt;
Din rezultatele de mai sus, rezultă că avem nevoie de un numărător pe 27 biți, astfel încât să putem folosi bitul cel mai semnificativ (bitul 26) pentru generarea semnalului de ceas cu frecvența cea mai mică.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea SystemVerilog a circuitului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module clock_generator(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic clkout1,&lt;br /&gt;
    output logic clkout2,&lt;br /&gt;
    output logic clkout4,&lt;br /&gt;
    output logic clkout8,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
logic [26:0] count;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        count &amp;lt;= 0;&lt;br /&gt;
    else&lt;br /&gt;
        count &amp;lt;= count + 1;  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
assign clkout1 = count[26];&lt;br /&gt;
assign clkout2 = count[25];&lt;br /&gt;
assign clkout4 = count[24];&lt;br /&gt;
assign clkout8 = count[23];&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Cerința ca reset să fie activ în 1 este impusă de logica în care lucrează butoanele FPGA-ului.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea circuitului pe FPGA&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Realizați sinteza circuitului pe FPGA, ținând cont de următoarele constrângeri de I/O:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
||&amp;#039;&amp;#039;&amp;#039;Port&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;Conexiune&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| clock || CLK_100MHz&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| reset || Button 0 &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| clkout1 || LED3&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| clkout2  || LED2&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| clkout4  || LED1 &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| clkout8  || LED0 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Observați viteza cu care fiecare din LED-uri se stinge și se aprinde.&lt;br /&gt;
&lt;br /&gt;
== Exerciții==&lt;br /&gt;
===Exercițiul 1===&lt;br /&gt;
Implementați un numărător parametrizat cu reset sincron și semnal de &amp;#039;&amp;#039;enable&amp;#039;&amp;#039;. Semnalul &amp;#039;&amp;#039;enable&amp;#039;&amp;#039; controlează funcționarea numărătorului astfel: când este activ (egal cu 1), permite funcționarea normală (incrementare la fiecare front crescător de ceas); când este inactiv (egal cu 0), va determina numărătorul să își păstreze valoarea curentă.&lt;br /&gt;
&lt;br /&gt;
Implementați și un modul de test care să testeze funcționarea corectă a circuitului.&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 2===&lt;br /&gt;
Implementați un numărător parametrizat cu reset sincron și capacitatea de a număra crescător sau descrescător. Controlul direcției de numărare se va realiza cu ajutorul unui semnal &amp;#039;&amp;#039;count_updown&amp;#039;&amp;#039;, care controlează funcționarea numărătorului astfel: când este 0, numărătorul va număra crescător, prin incrementarea valorii curente, iar când este 1, numărătorul va număra descrescător, prin decrementarea valorii curente&lt;br /&gt;
&lt;br /&gt;
Implementați și un modul de test care să testeze funcționarea corectă a circuitului.&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 3===&lt;br /&gt;
Implementați circuitul descris prin schema de mai jos, știind că:&lt;br /&gt;
* COUNTER este un numărător pe 32 biți fără reset.&lt;br /&gt;
* RAM este o memorie 16x4b, cu citire sincrona.&lt;br /&gt;
* ROM este o memorie 16x4b, ce are descrierea prezentată mai jos.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Cid_lab6.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea modulului ROM&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module ROM(&lt;br /&gt;
    input logic [3:0] in,&lt;br /&gt;
    output logic [3:0] out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
always_comb&lt;br /&gt;
    case(in)&lt;br /&gt;
        0: out = 4&amp;#039;b0000;&lt;br /&gt;
        1: out = 4&amp;#039;b0110;&lt;br /&gt;
        2: out = 4&amp;#039;b0011;&lt;br /&gt;
        3: out = 4&amp;#039;b1110;&lt;br /&gt;
        4: out = 4&amp;#039;b1011;&lt;br /&gt;
        5: out = 4&amp;#039;b1111;&lt;br /&gt;
        6: out = 4&amp;#039;b0111;&lt;br /&gt;
        7: out = 4&amp;#039;b1100;&lt;br /&gt;
        8: out = 4&amp;#039;b0001;&lt;br /&gt;
        9: out = 4&amp;#039;b0101;&lt;br /&gt;
        10: out = 4&amp;#039;b1101;&lt;br /&gt;
        11: out = 4&amp;#039;b1010;&lt;br /&gt;
        12: out = 4&amp;#039;b0010;&lt;br /&gt;
        13: out = 4&amp;#039;b0100;&lt;br /&gt;
        14: out = 4&amp;#039;b1000;&lt;br /&gt;
        15: out = 4&amp;#039;b1001;&lt;br /&gt;
        default: out = 4&amp;#039;b0000;&lt;br /&gt;
    endcase&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Realizați un modul de test în care să scrieți memoria RAM cu date, astfel încât să se realizeze citirea memoriei ROM în ordine, la fiecare ciclu de ceas (adresa 0 -&amp;gt; adresa 1 -&amp;gt; ... -&amp;gt; adresa 15 -&amp;gt; adresa 0 -&amp;gt; ...)&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_7_:_Circuite_secventiale_elementare&amp;diff=8331</id>
		<title>CID aplicatii 7 : Circuite secventiale elementare</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_7_:_Circuite_secventiale_elementare&amp;diff=8331"/>
		<updated>2026-04-23T10:55:19Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exemplul 3: Descrierea comportamentală a bistabilului de tip D */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Hazardul combinațional== &lt;br /&gt;
&lt;br /&gt;
Hazardul apare atunci când modificarea unei intrări a unui circuit combinațional determină modificări nedorite ale ieșirii. Aceste variații apar datorită diferențelor de întârzieri pe diverse căi de la intrare către ieșire.&lt;br /&gt;
&lt;br /&gt;
De unde aceste întârzieri? Fiecare poartă este, așa cum am văzut la începutul aplicațiilor, un circuit electronic format, de obicei, din tranzistoare MOS. Răspunsul acestor dispozitive nu este instantaneu, introducând întârzieri. Timpul scurs de la modificarea unei intrări a unei porți până la modificarea corespunzătoare a ieșirii se numește timp de propagare.&lt;br /&gt;
&lt;br /&gt;
În figura următoare avem evidențiat timpul de propagare printr-o poartă &amp;#039;&amp;#039;SAU&amp;#039;&amp;#039; (Tp). Acesta este reprezentat de timpul scurs de la modificarea lui a până la modificarea ieșirii.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Comutare poarta SAU.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
Avănd un circuit cu mai multe porți în cascadă, căile prin care anumite semnale ajung la intrările unei anumite porți pot diferi. Datorită timpilor de propagare diferiți care afectează aceste semnale până să ajungă la poarta curentă și a timpului de propagare efectiv al porții curente, pot apărea la ieșire tranziții nedorite ale semnalelor. Dacă la ieșire se așteaptă ca linia să rămană constant în 1, dar apare o scurtă tranziție prin 0, hazardul se numește &amp;#039;&amp;#039;1 static&amp;#039;&amp;#039;. Dacă la ieșire se așteaptă ca linia să rămană constant în 0, dar apare o scurtă tranziție prin 1, hazardul se numește &amp;#039;&amp;#039;0 static&amp;#039;&amp;#039;. Dacă se așteaptă o tranziție la ieșire, dar apare un regim tranzitoriu cu numeroase tranziții până la stabilizare, hazardul se numește dinamic.&lt;br /&gt;
&lt;br /&gt;
Pentru a înțelege mai bine, să considerăm exemplul de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Circuit comb hazard.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
Observăm că intrările porții &amp;#039;&amp;#039;P2&amp;#039;&amp;#039; urmează căi diferite: semnalul &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este ieșirea unei porți, având o întârziere cauzată de timpul de propagare al porții &amp;#039;&amp;#039;P1&amp;#039;&amp;#039;, pe când semnalul &amp;#039;&amp;#039;b&amp;#039;&amp;#039; vine direct de la intrare, propagarea prin fir fiind neglijabilă. Să considerăm cazul în care intrarea &amp;#039;&amp;#039;a&amp;#039;&amp;#039; rămane permanent în 0, iar intrarea &amp;#039;&amp;#039;b&amp;#039;&amp;#039; comută la un moment dat din 0 în 1. Inițial, semnalul &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 1, iar &amp;#039;&amp;#039;d&amp;#039;&amp;#039; este 1. După comutarea lui &amp;#039;&amp;#039;b&amp;#039;&amp;#039;, semnalul &amp;#039;&amp;#039;c&amp;#039;&amp;#039; va comuta din 1 in 0, iar &amp;#039;&amp;#039;d&amp;#039;&amp;#039; va rămane 1. Acesta este cazul ideal. În realitate, datorită timpilor de propagare ai porților logice &amp;#039;&amp;#039;P1&amp;#039;&amp;#039; și &amp;#039;&amp;#039;P2&amp;#039;&amp;#039;, vom avea o scurtă tranziție prin 0:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Circuit comb hazard propagare.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Atribuirea blocanta si non-blocanta==&lt;br /&gt;
Pentru ca simulatorul sa functioneze in mod corect si semnalele sa se modifice in simulare asa cum se modifica si in realitate este nevoie sa folosim atribuirea blocanta ( semnul &amp;quot;=&amp;quot;) la circuite combinationale si atribuirea non-blocanta (semnul &amp;quot;&amp;lt;=&amp;quot;) la circuite secventiale. &lt;br /&gt;
&lt;br /&gt;
In mod uzual orice always combinational ( &amp;#039;&amp;#039;&amp;#039;always_comb&amp;#039;&amp;#039;&amp;#039; ) va folosi &amp;#039;&amp;#039;&amp;#039;atribuirea blocanta ( = )&amp;#039;&amp;#039;&amp;#039; si orice always pe ceas ( &amp;#039;&amp;#039;&amp;#039;always_ff @(posedge clock)&amp;#039;&amp;#039;&amp;#039; ) va folosi &amp;#039;&amp;#039;&amp;#039;atribuirea non-blocanta ( &amp;lt;= )&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Diferenta dintre cele 2 atribuiri consta in modul in care simulatorul &amp;quot;executa&amp;quot; instructiunea de atribuire. La atribuirea blocanta se simuleaza linie cu linie, in ordinea in care acestea au fost scrise. La atribuirea non-blocanta se salveaza toti termenii din dreapta si se pun deodata (in acelasi pas de simulare) in termenii din stanga. Pentru a clarifica acest concept avem exemplul de mai jos: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
a = b;&lt;br /&gt;
b = a;&lt;br /&gt;
&lt;br /&gt;
c &amp;lt;= d;&lt;br /&gt;
d &amp;lt;= c;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In primul caz, deoarece am folosit atribuirea blocanta, a ia valoarea lui b si apoi b ia valoarea lui a, care deja a devenit b deci concret b ramane pe loc si deci atat a cat si b vor avea aceasi valoare la final.&lt;br /&gt;
&lt;br /&gt;
In al doilea caz, deoarece am folosit atribuirea non-blocanta, ce este in partea dreapta se transfera peste operanzii din stanga deodata, astfel c ia valoarea lui d si d ia valoarea lui c, la final avand loc o interschimbare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Latch-ul==&lt;br /&gt;
Latch-urile sunt dispozitive elementare de memorare, sensibile la nivelul semnalelor de intrare. Exemple de astfel de dispozitive sunt latch-urile de tip SR și latch-urile de tip D.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Latch-ul SR===&lt;br /&gt;
Latch-ul de tip SR poate fi realizat cu două porți &amp;#039;&amp;#039;SI NU&amp;#039;&amp;#039; sau &amp;#039;&amp;#039;SAU NU&amp;#039;&amp;#039; și este un dispozitiv asincron controlat de stările semnalelor &amp;#039;&amp;#039;S&amp;#039;&amp;#039; (set) și &amp;#039;&amp;#039;R&amp;#039;&amp;#039; (reset). Tabelul de adevăr al acestui circuit este prezentat mai jos. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Latch SR.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Atunci când &amp;#039;&amp;#039;S&amp;#039;&amp;#039; este 1 și &amp;#039;&amp;#039;R&amp;#039;&amp;#039; este 0, ieșirea &amp;#039;&amp;#039;Q&amp;#039;&amp;#039; va deveni 1, iar &amp;#039;&amp;#039;Qn&amp;#039;&amp;#039; va deveni 0. Atunci când &amp;#039;&amp;#039;R&amp;#039;&amp;#039; este 1 și &amp;#039;&amp;#039;S&amp;#039;&amp;#039; este 0, ieșirea &amp;#039;&amp;#039;Q&amp;#039;&amp;#039; se resetează (devine 0), iar &amp;#039;&amp;#039;Qn&amp;#039;&amp;#039; devine 1. Starea de memorare apare atunci când atât &amp;#039;&amp;#039;R&amp;#039;&amp;#039; cât și &amp;#039;&amp;#039;S&amp;#039;&amp;#039; sunt 0 în același timp. Cazul în care &amp;#039;&amp;#039;R&amp;#039;&amp;#039; și &amp;#039;&amp;#039;S&amp;#039;&amp;#039; sunt 1 în același timp duce la un comportament nedorit. (atât &amp;#039;&amp;#039;Q&amp;#039;&amp;#039; cât și &amp;#039;&amp;#039;Qn&amp;#039;&amp;#039; vor fi 0, ceea ce este incorect din punct de vedere al logicii dorite – &amp;#039;&amp;#039;Qn&amp;#039;&amp;#039; să fie negatul lui &amp;#039;&amp;#039;Q&amp;#039;&amp;#039;). În plus, dacă din aceasta stare se dorește trecerea în starea de memorare (&amp;#039;&amp;#039;R&amp;#039;&amp;#039; = 0, &amp;#039;&amp;#039;S&amp;#039;&amp;#039; = 0), poate apărea oscilația. În realitate, cele două porți nu vor avea același timp de propagare datorită variațiilor de producție și circuitul va ajunge în cele din urma într-o stare stabilă, nepredictibilă.&lt;br /&gt;
&lt;br /&gt;
===Latch-ul de tip D===&lt;br /&gt;
Latch-ul de tip D elimină problema combinațiilor nedorite de la ieșire. Acesta modifică ieșire doar atunci când semnalul de enable (&amp;#039;&amp;#039;E&amp;#039;&amp;#039;) este 1. Altfel, atunci când &amp;#039;&amp;#039;E&amp;#039;&amp;#039; este 0, va memora starea anterioara (&amp;#039;&amp;#039;Qt-1&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Latch D.png|500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Bistabilul de tip D==&lt;br /&gt;
Bistabilul de tip D este un dispozitiv de memorare ce salvează valoarea intrării pe unul din fronturile ceasului (în mod uzual, frontul crescător). El poate fi obținut prin conectarea a două latch-uri de tip D, conform schemei de mai jos. De obicei, singura ieșire care ne interesează este &amp;#039;&amp;#039;Q&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Bistabil D.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Comportamentul bistabilului de tip D poate fi observat în forma de undă următoare. Modificările lui &amp;#039;&amp;#039;data_out&amp;#039;&amp;#039; sunt determinate de fronturile crescătoare ale semnalului &amp;#039;&amp;#039;clock&amp;#039;&amp;#039;. La apariția acestora, &amp;#039;&amp;#039;data_out&amp;#039;&amp;#039; va lua valoarea intrării &amp;#039;&amp;#039;data_in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Forma unda bistabil.png]]&lt;br /&gt;
&lt;br /&gt;
===Bistabilul de tip D cu reset sincron===&lt;br /&gt;
Resetarea unui bistabil înseamnă aducerea valorii memorate la 0 sau la o altă valoare de reset definită de cel care proiectează circuitul. Vom considera în exemplul nostru că semnalul de &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; va fi activ în 0 și va face 0 valoarea memorată atunci când este activ. Un reset sincron înseamnă că acesta va acționa asupra valorii memorate&amp;#039;&amp;#039;data_out&amp;#039;&amp;#039; pe frontul crescător al ceasului.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Forma unda bistabil reset sincron.png]]&lt;br /&gt;
&lt;br /&gt;
===Bistabilul de tip D cu reset asincron===&lt;br /&gt;
Un reset asincron înseamnă că acesta va acționa asincron, fără a ține cont de ceas. Acest lucru înseamnă că el va acționa asupra valorii memorate imediat ce devine activ. În exemplele noastre, vom considera semnalul de &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; ca fiind activ în 0. Trecerea sa în 0 (frontul căzător) determină imediat resetarea circuitului. De asemenea, orice eveniment de front crescător de ceas ce apare cât timp reset-ul este activ, va duce la menținerea resetării circuitului. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Forma unda bistabil reset asincron.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
===Exemplul 1: Evidențierea hazardului combinațional===&lt;br /&gt;
&lt;br /&gt;
Implementați circuitul cu porți logice prezentat în secțiunea de introducere teoretică și reproduceți în modulul de testare variațiile semnalelor &amp;#039;&amp;#039;a&amp;#039;&amp;#039; și &amp;#039;&amp;#039;b&amp;#039;&amp;#039; propuse, astfel încât să observăm pe ieșirea &amp;#039;&amp;#039;d&amp;#039;&amp;#039; hazardul.&lt;br /&gt;
&lt;br /&gt;
Deoarece în simulare propagarea este ideală, va trebui să introducem un timp de propagare folosind &amp;#039;&amp;#039;#n&amp;#039;&amp;#039;. Acesta va avea efect doar în simulare și va fi ignorat la o eventuală sinteză.&lt;br /&gt;
&lt;br /&gt;
Pentru modulul de test, va trebui să alegem un timp de modificare a valorilor semnalelor mai mare decât timpul de propagare ales. Aici, vom folosi 1ns timp de propagare și 5ns timp de variație a intrărilor in testbench.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea SystemVerilog a circuitului&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;
`timescale 1ns/1ps&lt;br /&gt;
module Circuit(&lt;br /&gt;
    input logic a,&lt;br /&gt;
    input logic b,&lt;br /&gt;
    output logic c,&lt;br /&gt;
    output logic d&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
assign #1 c = ~(a | b);&lt;br /&gt;
assign #1 d = ~(c &amp;amp; b);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test care să evidențieze hazardul&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps&lt;br /&gt;
&lt;br /&gt;
module Circuit_TB();&lt;br /&gt;
&lt;br /&gt;
logic a_t, b_t;&lt;br /&gt;
logic c_t, d_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       a_t = 0;&lt;br /&gt;
       b_t = 0;&lt;br /&gt;
    #5 b_t = 1;&lt;br /&gt;
    #5 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
Circuit DUT(&lt;br /&gt;
    .a(a_t),&lt;br /&gt;
    .b(b_t),&lt;br /&gt;
    .c(c_t),&lt;br /&gt;
    .d(d_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Poza_hazard.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
In acest exemplu se observa ca iesirea c se modifica la 1ns dupa modificarile intrarilor (intarizerea adaugata pentru transmiterea prin porti) si iesirea d se modifica de 2 ori: prima data la 1ns din cauza intrarilor si a doua oara dupa inca 1ns din cauza lui c. In intervalul [6-7]ns apare o valoare parazita, un hazard.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Descrierea comportamentală a latch-ului de tip D===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea SystemVerilog a modulului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module latch_D(&lt;br /&gt;
    input logic D,&lt;br /&gt;
    input logic E,&lt;br /&gt;
    output logic Q&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
assign Q = (E == 1) ? D : Q;&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Modul de test pentru latch-ul D&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps&lt;br /&gt;
&lt;br /&gt;
module latch_D_TB();&lt;br /&gt;
&lt;br /&gt;
logic D_t, E_t;&lt;br /&gt;
logic Q_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       D_t = 0;&lt;br /&gt;
       E_t = 1;&lt;br /&gt;
    #1 D_t = 1;&lt;br /&gt;
    #1 D_t = 0;&lt;br /&gt;
    #1 E_t = 0;&lt;br /&gt;
    #1 D_t = 1;&lt;br /&gt;
    #1 D_t = 0;&lt;br /&gt;
    #5 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
latch_D DUT1(&lt;br /&gt;
    .D(D_t),&lt;br /&gt;
    .E(E_t),&lt;br /&gt;
    .Q(Q_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exemplul 3: Descrierea comportamentală a bistabilului de tip D===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea SystemVerilog a modulului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module flipflop_D(&lt;br /&gt;
    input logic data_in,&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    output logic data_out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    data_out &amp;lt;= data_in; // atribuire non-blocanta&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;
&amp;#039;&amp;#039;&amp;#039;Modulul de test pentru bistabilul de tip D&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps&lt;br /&gt;
&lt;br /&gt;
module flipflop_D_TB();&lt;br /&gt;
&lt;br /&gt;
logic data_in_t, clock_t;&lt;br /&gt;
logic data_out_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       data_in_t &amp;lt;= 0;&lt;br /&gt;
    #2 data_in_t &amp;lt;= 1;&lt;br /&gt;
    #4 data_in_t &amp;lt;= 0;&lt;br /&gt;
    #5 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~ clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
flipflop_D DUT(&lt;br /&gt;
    .data_in(data_in_t),&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .data_out(data_out_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Atunci cand avem un circuit secvential, se foloseste atribuirea non-blocanta (&amp;quot;&amp;lt;=”)&lt;br /&gt;
&lt;br /&gt;
==Exerciții==&lt;br /&gt;
===Exercițiul 1===&lt;br /&gt;
Descrieți structural latch-ul de tip SR, conform schemei din secțiunea de introducere teoretică. Puteți simula întârzierile prin porți folosind #1.&lt;br /&gt;
&lt;br /&gt;
Realizați un modul de test care să pună în evidență funcționarea. Respectați la generarea stimulilor următoarea variație (fiecare segment de timp durează 5ns).&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Forma unda latchSR.png]]&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 2===&lt;br /&gt;
Modificați descrierea bistabilului de tip D prezentată în exemple, astfel încât acesta să permită resetarea sincronă. Semnalul de reset va fi activ în 0.&lt;br /&gt;
&lt;br /&gt;
Realizați un modul de test care să respecte la generarea stimulilor forma de unda prezentată în secțiunea de introducere teoretică, la &amp;#039;&amp;#039;&amp;#039;Bistabilul de tip D cu reset sincron&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 3===&lt;br /&gt;
Modificați descrierea bistabilului de tip D prezentată în exemple, astfel încât acesta să permită resetarea asincronă. Semnalul de reset va fi activ în 0.&lt;br /&gt;
&lt;br /&gt;
Realizați un modul de test care să respecte la generarea stimulilor forma de unda prezentată în secțiunea de introducere teoretică, la &amp;#039;&amp;#039;&amp;#039;Bistabilul de tip D cu reset asincron&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Indicație&amp;#039;&amp;#039;&amp;#039;: Frontul căzător al semnalului &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; va trebui să fie adăugat în lista de sensitivități a blocului always care determină modificarea lui &amp;#039;&amp;#039;data_out&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 4===&lt;br /&gt;
Pentru evidentierea hazardului combinational (si a modului in care acesta se rezolva) descrieti in SystemVerilog si simulati urmatoarele 2 circuite:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Poza_circ_secventiale_basic_exercitiu_4_circuit.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru a putea observa efectele hazardului, portile trebuie descrise ca avand timpi de propagare.&lt;br /&gt;
&lt;br /&gt;
Formele de unda pentru semnalele de la intrare vor fi:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Poza_circ_secventiale_basic_exercitiu_4_forme_unda.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 5===&lt;br /&gt;
Pentru evidentierea efectului atribuirii blocant si non-blocante se va implementa si simula circuitul de mai jos. El este alcatuit din 3 registre, fiecare memorand (si punand la iesire) pe frontul pozitiv al ceasului valoarea de la intrare.&lt;br /&gt;
&lt;br /&gt;
Cele 3 registre de sus vor folosii atribuirea blocanta si cele 3 registre de jos vor folosii atribuirea non-blocanta. In simulare se doreste a se vizualiza: intrarile, iesirile, firele interne de legatura dintre registrii.&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie semnificativ mai putin, nu este nevoie sa instantiati fiecare registru dintro serie ca modul separat ci se pot face toate cele 3 atribuiri in cadrul aceluiasi bloc &amp;quot;always&amp;quot;, la nivelul de top. Practic tot circuitul se reduce la un fisier de top ce contine intrari/iesiri, declararea registrilor pe 1b si cele 2 always-uri care dicteaza functionarea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Poza_circ_secventiale_basic_exercitiu_5_circuit.png ‎| 600px]]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8323</id>
		<title>CID aplicatii 5 : Exercitii cu circuite combinationale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8323"/>
		<updated>2026-04-06T16:41:04Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exercitiul 0: Repararea erorilor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostiintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 1 in anii anteriori si cateva notiuni de teorie si sintaxa ajutatoare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: Parametrizare==&lt;br /&gt;
Parametrizarea este un mod de a generaliza codul scris pentru a nu fi necesara descrierea aceluiasi modul de mai multe ori (daca circuitul isi schimba o dimensiune). &lt;br /&gt;
&lt;br /&gt;
Pentru a intelege mai clar avantajele si sintaxa urmariti urmatorul exemplu:&lt;br /&gt;
&lt;br /&gt;
Fisierul sumator.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator # // &amp;lt;= diez deoarece urmeaza lista cu parametri&lt;br /&gt;
				( // parametri &lt;br /&gt;
					parameter data_size = 4 // valoare default 4&lt;br /&gt;
					// alti parametri aici daca este nevoie, separati prin virgula&lt;br /&gt;
				)&lt;br /&gt;
				( // interfata &lt;br /&gt;
					input logic [data_size-1:0] in0, // si pot folosi parametrul &amp;quot;data_size&amp;quot; pentru dimensiunea bus-ului&lt;br /&gt;
					input logic [data_size-1:0] in1,&lt;br /&gt;
					output logic [data_size-1:0] out0&lt;br /&gt;
				);&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 + in1;				&lt;br /&gt;
				&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cand se instantiaza un modul parametrizat, se specifica valorile parametrilor astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(8)   // se genereaza un sumator pe 8b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_0&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out0)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(32)  // se genereaza un sumator pe 32b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_1&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator nume_instanta_2 // se genereaza un sumator de dimensiune default, aici 4, asa cum e scris in modulul &amp;quot;sumator&amp;quot;&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out2)&lt;br /&gt;
	);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puteti folosi parametrizarea in exercitiul 3 de mai jos. Acolo sunt 2 tipuri de multiplexoare, unul cu intrarile pe 1 bit si unul cu intrarile pe 2 biti. Poate fi scris un singur modul parametrizat care sa acopere ambele situatii.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Concatenarea==&lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara conectare a firelor sau pentru o mai buna organizare si expresivitate a codului, de multe ori este util ca fire individuale sa fie grupate impreuna sau ca un bus de mai multi biti sa fie separat in fire individuale. Acest lucru se face folosind concatenarea, prin simbolurile &amp;quot;{ }&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Un exemplu de folosire a concatenarii este oferit mai jos.&lt;br /&gt;
Un sumator pe 8b are rezultatul pe maxim 9b, in cazul in care ambele numere sunt mari. Astfel apare un bit de carry out. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator ( &lt;br /&gt;
            input logic [7:0] in0,&lt;br /&gt;
            input logic [7:0] in1,&lt;br /&gt;
            output logic [7:0] out0,&lt;br /&gt;
            output logic carry_out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign {carry_out,out0} = in0 + in1; // fac suma intre in0 si in1 iar rezultatul il pun pe cei 9b alcatuiti din: 1b carry_out si 8b out0, in ordinea asta&lt;br /&gt;
&lt;br /&gt;
endmodule       &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Se pot concatena oricat de multe semnale, puse in &amp;quot;{ }&amp;quot; si separate prin virgula. Atentie la dimensiunile firelor care se concateneaza.&lt;br /&gt;
&lt;br /&gt;
Se poate de asemenea face concatenare si la dreapta egalului, astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fir_pe_10_b = {fir_pe_3b,fir_pe_5b,fir_pe_1b,fir_pe_1b};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In exemplul anterior ultimi 2b ai &amp;quot;fir_pe_10_b&amp;quot; vor avea mereu aceeasi valoare, provenind din acelasi fir. Sintaxa SystemVerilog permite asta.&lt;br /&gt;
&lt;br /&gt;
Puteti folosii concatenarea, in exercitiul 2, la flag-ul de overflow.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Constante ca intrari in circuite==&lt;br /&gt;
In cazul in care se doreste scrierea unor constante la intrarea unor module, acestea se pun direct intre paranteze la instantiere. &lt;br /&gt;
De exemplu, pentru multiplexorul de jos din subiectul &amp;quot;alu structural&amp;quot;, intrarea &amp;quot;in3&amp;quot; este conectata la valoarea &amp;quot;1&amp;quot;. Sintaxa pentru aceasta este: &amp;quot;.in3(1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: &amp;quot;_&amp;quot;==&lt;br /&gt;
Simbolul &amp;quot;_&amp;quot; (underscore) este ignorat de SystemVerilog si ajuta vizual la citirea semnalelor pe mai multi biti. De exemplu 16&amp;#039;b1010010111110000 este identic cu 16&amp;#039;b1010_0101_1111_0000, al doilea fiind totusi mai usor de citit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 0: Repararea erorilor===&lt;br /&gt;
Arhiva de mai jos contine mai multe proiecte in Vivado, fiecare avand cate o eroare de sintaxa sau de logica. In vederea aprofundari cunostiintelor voastre (si pentru lucrarea de saptamana urmatoare), incercati sa le parcurgeti si sa rezolvati toate problemele. &lt;br /&gt;
Pe langa proiecte in sine, in arhiva se afla si un fisier text cu o introducere, rezolvarile si explicatiile pentru fiecare situatie.&lt;br /&gt;
&lt;br /&gt;
[https://drive.google.com/file/d/1uOdI88CL0zUiW1hvgnU5H-K-AnNTWCLK/view?usp=sharing Arhiva_proiecte_cu_erori.zip]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: ALU - descriere comportamentala===&lt;br /&gt;
Descrieți comportamental o unitate aritmetico-logică (ALU) care are la intrare 2 numere binare de câte 8 biți și poate calcula următoarele funcții:&lt;br /&gt;
:- suma celor două numere&lt;br /&gt;
:- diferența celor două numere&lt;br /&gt;
:- operații logice bit cu bit (bitwise): SI, SAU, XOR și inversele lor&lt;br /&gt;
:- operandul din stanga trece neschimbat&lt;br /&gt;
:- operandul din dreapta trece neschimbat&lt;br /&gt;
:- numărul din stânga este deplasat la stânga cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
:- numărul din stânga este deplasat la dreapta cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
&lt;br /&gt;
Funcția executată la un anumit moment este determinată de configurația binară de pe intrarea de comandă (function).&lt;br /&gt;
&lt;br /&gt;
ALU are de asemenea intrare de carry și ieșire de carry, plus alte două ieșiri - indicatori - pentru cazurile când rezultatul este zero și când cei doi operanzi sunt egali.&lt;br /&gt;
&lt;br /&gt;
Intrarea de control va fi facuta pe 4 biti ca sa permita existenta a 16 operatii posibile. Fiecare numar de pe intrarea de control (combinatie de 0 si 1) va reprezenta o operatie din cele de mai sus. Scrierea se va face folosind un bloc &amp;quot;case&amp;quot; in functie de aceasta intrare. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: ALU - descriere structurala===&lt;br /&gt;
 &lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/8f/Subiect_big_alu.pdf subiect_alu.pdf]&lt;br /&gt;
	&lt;br /&gt;
Daca se doreste selectarea doar a anumitor biti dintr-un bus (cum se vrea din instruction) acest lucru se poate face in 2 feluri:&lt;br /&gt;
&lt;br /&gt;
a) cu fir aditional:&lt;br /&gt;
:&amp;#039;&amp;#039;wire [1:0] fir_aditional1;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;assign fir_aditional1 = instruction[11:10];&amp;#039;&amp;#039;&lt;br /&gt;
:// apoi la instantiere: &amp;#039;&amp;#039;.sel(fir_aditional1),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
b) direct in instantiere;&lt;br /&gt;
:la instantierea celor 2 mux4 din stanga, direct: &lt;br /&gt;
::&amp;#039;&amp;#039;.sel(instruction[11:10]),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie mai putin (a nu face toate modulele de calcul separat + instantierea lor) si pentru ca e vorba de operatii simple, se poate pune operatia cu assign direct in top pe un fir declarat acolo, sau si mai prescurtat, direct operatia dorita cand se intantiaza modulul in care aceasta intra. De exemplu, pentru operatia de shift la dreapta care intra in primul multiplexor, se poate pune:  &amp;quot;.in0(data0 &amp;gt;&amp;gt; data1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Multiplexoare===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/3/3a/Subiect_muxes.pdf subiect_muxes.pdf]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Rom/Look-up table===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2e/Subiect_rom_luts.pdf rom_luts.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Sumator cu reprezentare in cifre zecimale===&lt;br /&gt;
Proiectati si verificati un sumator zecimal pentru numere cu 2 cifre&lt;br /&gt;
&lt;br /&gt;
Modulul de top (Figura 1) este alcatuit din 2 blocuri de tip &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;. Fiecare bloc aduna cifrele de pe aceasi pozitie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 1&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
   Top level&lt;br /&gt;
&lt;br /&gt;
[[Fișier: bcdsum.png]]&lt;br /&gt;
&lt;br /&gt;
Blocul &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; (Figura 2) este alcatuit din 4 blocuri, 2 sumatoare binare pe 4 biti (de tip &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039;), o instanta de &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039; si un multiplexor elementar mux2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 2&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
   Blocul DIGIT SUM &lt;br /&gt;
&lt;br /&gt;
[[Fișier: digit.png]]&lt;br /&gt;
&lt;br /&gt;
Primul sumator aduna cifrele din domeniul [0...9] avand un rezultat intre [0 ... 18] &lt;br /&gt;
&lt;br /&gt;
Comparatorul are la iesire 1 daca rezultatul este mai mare decat 9.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mic decat 9, acesta este trimis in mod direct la iesirea &amp;#039;&amp;#039;&amp;#039;digit&amp;#039;&amp;#039;&amp;#039; a blocului &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mare decat 9, o crectie este necesara si se aduna 6 la rezultat.&lt;br /&gt;
&lt;br /&gt;
Comparatorul cu valoarea 9 este descris structural din porti in figura de mai jos: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 3&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
   the comparator &lt;br /&gt;
&lt;br /&gt;
[[Fișier: cmp.png]]&lt;br /&gt;
&lt;br /&gt;
Testbench-ul va genera stimuli pentru &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
Intrarea b0 a &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; se schimba la fiecare 5 pasi de simulare .&lt;br /&gt;
&lt;br /&gt;
b1, a0 si a1 se schimba sincron cu b0 ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: teststimuli.png]]&lt;br /&gt;
&lt;br /&gt;
Cerinte:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039;- descris structural la nivel de porti ca in Figura 3.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039; descris comportamental cu un assign continuu.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;mux&amp;#039;&amp;#039;&amp;#039; descris comportamental cu always.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; descris strctural ca in Figura 2.&lt;br /&gt;
# modulul de top numit &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039;, descris structural ca in Figure 1.&lt;br /&gt;
# modulul de testbench, &amp;#039;&amp;#039;&amp;#039;bcdsum_tb&amp;#039;&amp;#039;&amp;#039;, instantiaza &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; cu numele &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# in testbench, generati stimuli pentru intrarile circuitului testat.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Codor Cezar===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/9/92/Cid_L1_codor_Cezar.pdf Codor_Cezar.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 7: Calcul si Flag-uri===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/c/c2/L1_calcul_si_flaguri.pdf Calcul_si_flaguri.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 8: Unitate aritmetico-logică (ALU)===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/85/Subiect_ALU_pentru_wiki.pdf Unitate_aritmetico-logica]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=8318</id>
		<title>CID aplicatii 2 : Instantiere si porti logice</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=8318"/>
		<updated>2026-04-03T08:44:24Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exemplul 2: NAND2 din AND2 si NOT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie: incapsulare si instantiere==&lt;br /&gt;
Unitatile constructive de baza din care se formeaza circuitele digitale se numesc porti logice. Acestea implementeaza functii logice si prin conectarea mai multor astfel de circuite simple complexitatea unui circuit poate creste pana la nivelul procesoarelor actuale. Pentru a putea controla cresterea complexitatii in proiectarea unui circuit de dimensiuni mari se folosesc 2 concepte cheie: &lt;br /&gt;
&lt;br /&gt;
1) incapsularea functiei dorite intr-un modul&lt;br /&gt;
&lt;br /&gt;
2) instantierea unor module mai mici si asamblarea acestora pentru a forma un modul mai mare. &lt;br /&gt;
&lt;br /&gt;
Incapsularea se refera la a grupa elementele ce alcatuiesc o anumita functionalitate intr-un modul. Aceste elemente pot la randul lor sa fie alte module.&lt;br /&gt;
Instantierea (asemanator cu POO) se refera la a apela un modul deja scris pentru a fi folosit efectiv in circuitul curent. &lt;br /&gt;
Pentru a face o analogie cu programarea, cand se declara o variabila (sau un obiect), tipul variabilei este echivalent cu modulul si numele ei este numele instantei.&lt;br /&gt;
&lt;br /&gt;
Pentru a intelege aceste concepte se da circuitul de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_instantiere.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1) Notatie aici: Numele modulului este scris in interior. &lt;br /&gt;
&lt;br /&gt;
2) Notatie aici: Numele instantei este scris deasupra.&lt;br /&gt;
&lt;br /&gt;
3) Idee fundamentala: prin instantierea si incapsularea unor circuite simple, mici, apar circuite mai complexe.&lt;br /&gt;
&lt;br /&gt;
4) Idei esentiale (daca vreuna e neclara consultati cadrul didactic): &lt;br /&gt;
&lt;br /&gt;
:a) &amp;quot;modul_2&amp;quot; este instantiat o singura data in tot proiecul, iar instanta se cheama &amp;quot;x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:b) &amp;quot;modul_2&amp;quot; are o intrare numita &amp;quot;in0&amp;quot; si o iesire numita &amp;quot;out0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:c) &amp;quot;modul_2&amp;quot; este instantiat in cadrul &amp;quot;modul_6&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:d) Modulul cel mai mare, ce cuprinde toata functionalitatea dorita a sistemului (aici &amp;quot;modul_6&amp;quot;) se numeste uzual top.&lt;br /&gt;
&lt;br /&gt;
:e) Instanta top-ului care apare atunci cand se doreste testarea sa in simulare intr-un testbench (tb) se numeste uzual DUT (design under test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:f) &amp;quot;modul_0&amp;quot; apare instantiat de 3 ori. Circuitul final, cuprinde 3 subcircuite de tip &amp;quot;modul_0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:g) La nivel de top, instanta sa se cheama &amp;quot;b&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
:h) La nivel de &amp;quot;modul_5&amp;quot;, cele 2 instante se cheama &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:i) &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot; sunt 2 circuite fizice diferite chiar daca ambele sunt de tipul &amp;quot;modul_0&amp;quot;. Fiind instante ale aceluiasi modul, deci identice in alcatuire, luate separat ele fac acelasi lucru. Luate in contextul lui &amp;quot;modul_5&amp;quot;, &amp;quot;a&amp;quot; genereaza datele de pe firul &amp;quot;w0&amp;quot; si &amp;quot;c&amp;quot; genereaza datele pentru iesire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:j) circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_1&amp;quot; (instantiat in &amp;quot;modul_5&amp;quot;) este complet diferit de circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_0&amp;quot; (instantiat in top). Este permis ca ele sa aiba acelasi nume (cele 2 instante) deoarece se afla in locatii diferite. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:k) Identic, mai multe module au o intrare numita &amp;quot;in_0&amp;quot;. La sinteza circuitului nu se face confuzie intre acestea deoarece fiecare e vazut la nivelul altei instante.&lt;br /&gt;
&lt;br /&gt;
:l) Identic, firele de legatura &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:m) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w2&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;b&amp;quot; la intrarea &amp;quot;in2&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:n) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;x&amp;quot; la intrarea &amp;quot;in1&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:o) La nivelul &amp;quot;modul_5&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea instantei &amp;quot;b&amp;quot; la intrarea instantei &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:Pentru claritatea desenului, respectivele intrari si iesiri nu au fost denumite. In cod este obligatoriu ca ele sa fie definite si denumite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:p) La nivelul &amp;quot;top&amp;quot;, &amp;quot;in0&amp;quot;,&amp;quot;in1&amp;quot;,&amp;quot;in2&amp;quot;,&amp;quot;in3&amp;quot;,&amp;quot;in4&amp;quot; si &amp;quot;out0&amp;quot; formeaza interfata modulului (semnalele care intra sau ies din modul).&lt;br /&gt;
&lt;br /&gt;
:q) La nivelul &amp;quot;top&amp;quot;, &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;, &amp;quot;w2&amp;quot; sunt fire interne de legatura.&lt;br /&gt;
&lt;br /&gt;
:r) La nivelul &amp;quot;top&amp;quot;, firul &amp;quot;in3&amp;quot; este conectat ca intrare pentru 3 submodule.&lt;br /&gt;
&lt;br /&gt;
==Teorie: testarea circuitelor==&lt;br /&gt;
Pentru a se testa functionarea corecta a circuitului final, acesta este instantiat intr-un modul numit &amp;quot;test_bench&amp;quot; sau &amp;quot;tb&amp;quot;. Acest modul este folosit strict in simulare. &lt;br /&gt;
Testarea unui circuit are loc conform schemei urmatoare: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_tb.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Generarea datelor de intrare se va face asemanator cu laboratorul 1.&lt;br /&gt;
&lt;br /&gt;
Voi veti avea rolul modelului ideal si al comparatorului datelor de iesire, uitandu-va la datele de intrare veti calcula iesirea corecta si apoi veti compara aceasta valoare cu raspunsul circuitului ce se testeaza.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In cazul unui sistem automat, se genereaza mesaje de eroare sau mesaje ca functionarea este in regula.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Observatie: proiectarea si verificarea sunt 2 domenii diferite, firmele avand departamente separate pentru acestea. &lt;br /&gt;
&lt;br /&gt;
Proiectarea/Design se ocupa cu scrierea in Verilog/SystemVerilog a modului de top si toate modulele ce se afla in acesta, avand ca scop final realizarea fizica pe placa a unui circuit. &lt;br /&gt;
&lt;br /&gt;
Verificarea se ocupa de scrierea in SystemVerilog (limbaj format din Verilog cu concepte de POO) a modului de testbench si generarea de stimuli si scenarii care sa testeze functionarea design-ului.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: porti logice==&lt;br /&gt;
Portile logice folosite uzual, impreuna cu tabelele lor de adevar si reprezentarea grafica sunt date mai jos.&lt;br /&gt;
&lt;br /&gt;
Se folosesc porti logice cu 1 sau 2 intrari, cele cu mai mult de 2 intrari fiind construite din acestea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tip !! Simbol !! Tabel de adevăr !! Tip !! Simbol !! Tabel de adevăr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Buffer/Repetor&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:Buffer_gate.png|Buffer symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOT&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:not.png|NOT symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || NOT A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;AND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:and.png|AND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A AND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NAND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nand.png|NAND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NAND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;OR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:or.png|OR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A OR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nor.png|NOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xor.png|XOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XNOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xnor.png|XNOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XNOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Despre FPGA==&lt;br /&gt;
FPGA-ul (Field-Programmable Gate Array) este un circuit programabil, capabil sa implementeze circuite definit de utilizator. El este format dintr-o matrice de blocuri programabile, interconectate intre ele printr-o serie de conexiuni la randul lor programabile.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cand se doreste implementarea unui circuit pe FPGA, acesta urmeaza urmatoarele etape: &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Elaborarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care codul SystemVerilog este transformat intr-un circuit la nivel de porti si registre (netlist) si este independent de modelul de FPGA folosit. &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Sinteza&amp;#039;&amp;#039;&amp;#039; este procesul în care se realizează transformarea circuitului descris într-un netlist dependent de tehnologie. Se vor folosi la acest pas primitivele disponibile pe FPGA.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Implementarea&amp;#039;&amp;#039;&amp;#039; este procesul în care se preia netlist-ul ce conține primitivele FPGA și modul lor de interconectare realizat la pasul de sinteză și se realizează maparea lor efectivă în FPGA (place and route).&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Generarea Bitstream-ului&amp;#039;&amp;#039;&amp;#039; este procesul prin care informatiile din implementare sunt asamblate intr-un singur fisier.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Programarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care fisierul generat anterior este trimis efectiv catre placa cu FPGA (prin USB) unde determina modificarea valorilor si conexiunilor interne din aceasta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O introducere mai detaliata poate fi gasita aici : [[FPGA - Introducere]].&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Fpgaimg.PNG|600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Pentru a putea controla circuitul propus si a putea vedea rezultatele, intrarile si iesirile (input si output din module) in/din acesta trebuie conectate la pini fizici ai FPGA-ului care sunt conectati la butoane/switch-uri/leduri.&lt;br /&gt;
* Conexiunile dintre butoane/switch-uri si pinii FPGA sunt fixe. La fel si cele intre pinii FPGA si LED-uri. (in functie de PCB)&lt;br /&gt;
* Conexiunile dintre porturile modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; si pinii FPGA sunt configurabile. (in functie de noi, prin fisierul XDC)&lt;br /&gt;
* Legarea porturilor modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; la pinii fizici ai FPGA se realizeaza prin configurarea conexiunilor din FPGA conform contrangerilor de I/O pe care le vom mentiona in proiect, inainte de sinteza.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 1: Analiza circuitelor cu porti===&lt;br /&gt;
Fie urmatorul circuit alcatuit din porti logice:&lt;br /&gt;
 [[Fișier:Mux2_schema_interna_2.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Se doreste exprimarea circuitului de mai sus ca formula de tip: iesire = f(intrari). &lt;br /&gt;
&lt;br /&gt;
Pentru asta, abordarea consta in a porni de la iesire si a merge pas cu pas catre intrari, asa cum este exemplificat mai jos. Se vor folosi simbolurile &amp;quot;~&amp;quot; pentru NOT, &amp;quot;&amp;amp;&amp;quot; pentru AND, &amp;quot;|&amp;quot; pentru OR.&lt;br /&gt;
:pas1: out0 = ?&lt;br /&gt;
:pas2: out0 = w1 | w2&lt;br /&gt;
:pas3: out0 = w1 | ( ? )&lt;br /&gt;
:pas4: out0 = w1 | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas5: out0 = ( ? ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas6: out0 = ( in0 &amp;amp; w0 ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas7: out0 = ( in0 &amp;amp; ( ? ) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas8: out0 = ( in0 &amp;amp; (~sel) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: NAND2 din AND2 si NOT===&lt;br /&gt;
In urmatorul exemplu se implementeaza o poarta NAND din o poarta AND si o poarta NOT. &lt;br /&gt;
&lt;br /&gt;
Codul de mai jos exemplifica ideea de instantiere si contine comentarii legate de sintaxa SystemVerilog necesara.&lt;br /&gt;
&lt;br /&gt;
In mod uzual fisierele sunt denumite dupa modulul ce se afla in ele, in fiecare fisier fiind un singur modul.&lt;br /&gt;
&lt;br /&gt;
Schema circuitul care se doreste a fi creat este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_exemplu_rezolvat.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii NOT (fisierul not_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
// comentarii cu &amp;quot;//&amp;quot; sau cu /* .... */ ;&lt;br /&gt;
/* &lt;br /&gt;
	ca in c/c++ &lt;br /&gt;
*/ &lt;br /&gt;
&lt;br /&gt;
module not_gate	// cuvant cheie &amp;quot;module&amp;quot; apoi numele modulului (asemanator clase din c++)&lt;br /&gt;
	( // intre paranteze se pune interfata (firele care intra sau ies din modul)&lt;br /&gt;
		input logic in0,         // in0 este o intrare =&amp;gt; input&lt;br /&gt;
		output logic out0	// out0 este o iesire =&amp;gt; output&lt;br /&gt;
	); // aici &amp;quot;;&amp;quot; sa nu il uitati&lt;br /&gt;
&lt;br /&gt;
assign out0 = ~in0;	// cuvant cheie assign; &lt;br /&gt;
					// semnalele pot lua valoare prin assign&lt;br /&gt;
					// ~ e semnul pentru negatie pe biti (ca in c/c++)&lt;br /&gt;
&lt;br /&gt;
endmodule // cuvant cheie &amp;quot;endmodule&amp;quot;. orice module se inchide cu endmodule.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii AND (fisierul and_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and_gate&lt;br /&gt;
	(&lt;br /&gt;
		input logic in0,	// aici sunt 2 intrari &lt;br /&gt;
		input logic in1,	&lt;br /&gt;
		output logic out0&lt;br /&gt;
	); // nu conteaza ordinea in care sunt puse intrarile si iesirile.&lt;br /&gt;
			// uzual si pentru usurinta se ordoneaza si grupeaza dupa functionalitate&lt;br /&gt;
			// in cazul de mai sus, am pus intai intrarile, apoi iesirile.&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 &amp;amp; in1; // operatia propriu zisa &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului top (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic a,&lt;br /&gt;
		input logic b,&lt;br /&gt;
		output logic c&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic w0;    //declarat un fir intern de legatura &lt;br /&gt;
    &lt;br /&gt;
and_gate and_gate_0	// instantiere: nume_modul nume_instanta (asemanator int x din c/c++)&lt;br /&gt;
	(&lt;br /&gt;
		.in0(a), // la intrarea &amp;quot;in0&amp;quot; a instantei &amp;quot;and_gate_0&amp;quot;  se conecteaza firul &amp;quot;a&amp;quot; din top&lt;br /&gt;
		.in1(b), // grija ca &amp;quot;in0&amp;quot;, &amp;quot;in1&amp;quot;, &amp;quot;out0&amp;quot; sa existe in declararea modulului &amp;quot;and_gate&amp;quot;&lt;br /&gt;
		.out0(w0) // grija ca &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;w0&amp;quot; sa existe la nivelul modulului in care se face instantierea&lt;br /&gt;
	);    &lt;br /&gt;
    &lt;br /&gt;
not_gate not_gate_0&lt;br /&gt;
	(&lt;br /&gt;
		.in0(w0), // &amp;quot;w0&amp;quot; care iese din &amp;quot;and_gate_0&amp;quot; intra in &amp;quot;not_gate_0&amp;quot;&lt;br /&gt;
		.out0(c) // &amp;quot;c&amp;quot; care iese din &amp;quot;not_gate_0&amp;quot; iese din modulul &amp;quot;top&amp;quot; (e iesire in interfata de sus)&lt;br /&gt;
	);   // se poate scrie si &amp;quot;.in0(w0),.out0(c)&amp;quot; dar se prefera fiecare fir pe randul sau (lizibilitate si loc de comentarii pt design-uri complexe)&lt;br /&gt;
	// Observatie: la varianta de mai sus de instantiere, nu conteaza ordinea firelor. &lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
not_gate not_gate_0		&lt;br /&gt;
	(				// se poate instantia si in forma prescurtata ca aici &lt;br /&gt;
		w0,				// in acest caz se pun conexiunile in ordinea in care sunt declarate intrarile si iesirile din modul&lt;br /&gt;
		c	// NU se recomanda stilul asta de instantiere&lt;br /&gt;
	); 			// apar greseli frecvent la ordinea firelor si la numarul lor, &lt;br /&gt;
*/				// mai ales daca modulul e complex si are multe intrari si intrari&lt;br /&gt;
 &lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Echivalent se pot folosi si &amp;quot;primitive&amp;quot; SystemVerilog pentru scrierea top-ului.&lt;br /&gt;
&lt;br /&gt;
Primitivele sunt circuite care exista deja in limbaj, folosite atunci cand se doreste o descriere structurala a circuitului.&lt;br /&gt;
&lt;br /&gt;
In instantiere acestora, iesirea se pune prima, urmata de intrari.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; daca se doreste scrierea acestor porti de catre voi (ca mai sus), numele modulului nu trebuie sa fie un cuvant cheie ocupat de primitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v2&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
  &lt;br /&gt;
logic w0;&lt;br /&gt;
&lt;br /&gt;
and and_gate_0(w0,a,b);	// primitiva pentru poarta and&lt;br /&gt;
not not_gate_0(c,w0);  	// primitiva pentru poarta not&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fiind un modul simplu, intreaga functionalitate putea fi scrisa la nivel de &amp;quot;top&amp;quot; si simplificat ca mai jos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v3.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v3&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
   &lt;br /&gt;
assign c = ~ (a &amp;amp; b); // a si b, negate&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Testarea circuitul se face printr-un testbench, acesta fiind:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea testbench-ului (fisierul top_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module top_tb(); // din/in tb nu intra si iese nimic. niciodata.&lt;br /&gt;
&lt;br /&gt;
logic a_tb;	&lt;br /&gt;
logic b_tb;	&lt;br /&gt;
logic c_tb;	&lt;br /&gt;
&lt;br /&gt;
top dut	// instantierea modulului de tip &amp;quot;top&amp;quot; sub numele &amp;quot;dut&amp;quot; &lt;br /&gt;
	(&lt;br /&gt;
		.a(a_tb),&lt;br /&gt;
		.b(b_tb),&lt;br /&gt;
		.c(c_tb)&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin // in loc de { ... } din c/c++, in SystemVerilog se pune begin ... end &lt;br /&gt;
	a_tb = 0;		// a_tb ia valoarea 0 la momentul 0 al simularii&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;		// dupa 10 unitati de timp (aici, 10ns)&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	&lt;br /&gt;
	#20 $stop();	// oprirea simularii &lt;br /&gt;
end //end pentru initial &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formele de unda rezultate din simulare se pot vedea mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:exemplu_rezolvat_nand_forme_de_unda.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In chenarul verde se pot observa instantele din simulare. &lt;br /&gt;
&lt;br /&gt;
Daca se doreste adaugarea de semnale noi pentru a fi vazute, se selecteaza modulul instantiat in care acestea se afla (chenar verde). &lt;br /&gt;
&lt;br /&gt;
Apoi, din chenarul rosu se aleg semnalele si se adauga prin click dreapta-&amp;gt;add to wave window. &lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara vizualizare, semnalele se pot grupa asa cum se vede in chenarul mov prin click dreapta-&amp;gt;new group.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se observa o functionare corecta circuitului, acesta fiind o poarta NAND. El scoate &amp;quot;0&amp;quot; cand ambele semnale de intrare sunt &amp;quot;1&amp;quot; si scoate &amp;quot;1&amp;quot; in rest.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea circuitului pe FPGA&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dupa ce circuitul a fost testat in simulare, se doreste punerea sa fizica pe placa FPGA. Pentru aceasta, se tine cont de urmatoarele.&lt;br /&gt;
&lt;br /&gt;
* Pentru a controla intrarile &amp;#039;&amp;#039;a&amp;#039;&amp;#039; si &amp;#039;&amp;#039;b&amp;#039;&amp;#039; ale circuitului &amp;#039;&amp;#039;&amp;#039;top&amp;#039;&amp;#039;, va trebui sa le conectam prin intermediul conexiunilor configurabile ale FPGA-ului la pini ce sunt mai departe conectati fizic la dispozitive ce pot controla valorile semnalelor (switch-uri, butoane).&lt;br /&gt;
* Pentru a observa valoarea iesirii, vom conecta semnalul de iesire &amp;#039;&amp;#039;c&amp;#039;&amp;#039;la un dispozitiv de observare, cum ar fi un LED, care va fi aprins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 1 si stins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 0.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:NAND2 FPGA.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru a realiza conectarea porturilor modulului &amp;#039;&amp;#039;top&amp;#039;&amp;#039; la pinii fizici ai FPGA ce sunt conectati mai departe la componentele de pe placa, va trebui sa specificam in utilitarul de sinteza maparea porturilor la acestia. Maparea se realizeaza prin mentionarea codurilor pinilor la care dorim conexiunea si poata numele de &amp;#039;&amp;#039;&amp;#039;constrangeri de I/O&amp;#039;&amp;#039;&amp;#039;. Aceste coduri sunt mentionate in documentatia placii de dezvoltare cu FPGA (in cazul nostru, Boolean Board) si pot fi regasite si in pagina [[Boolean Board - Pinout]].&lt;br /&gt;
&lt;br /&gt;
Conform schemei, la acest exemplu avem nevoie de codurile pinilor conectati mai departe la Switch0, Switch1 si LED0.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Daca intrarile si iesirile ar fi semnale pe mai multi biti, fiecare bit al intrarilor va fi conectat la cate un switch/buton si fiecare bit al iesirii va fi conectat la un LED. Acest lucru este necesar deoarece switch-urile/butoanele pot avea doar doua stari (0 si 1) si astfel pot controla un singur bit. La fel, un LED poate avea doar doua stari (0 - stins si 1 - aprins) si poate afisa starea unui singur bit.&lt;br /&gt;
&lt;br /&gt;
Dupa ce ati extras codurile necesare, urmati pasii descrisi in [[Tutorial_Vivado|tutorialul Vivado]]. &lt;br /&gt;
&lt;br /&gt;
Dupa programarea cu succes a placii, puteti testa functionalitatea circuitului prin modficarea valorilor switch-urilor si observarea starii LED-ului.&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
Pentru urmatoarele exercitii se doreste atat testarea designurilor prin simulare cat si punerea acestora pe placa. Legat de placa, intrarile vor fi conectate la butoane, iar iesirile la leduri. Se va consulta tabelul cu pini disponibili ([[Boolean Board - Pinout]].).&lt;br /&gt;
&lt;br /&gt;
Exista moduri mai rapide de a scrie functionalitatea dorita (vezi exemplu), dar tema principala a acestui laborator este instantierea, asa ca sunteti rugati sa respectati desenele si sa instantiati fiecare poarta individual.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: AND4 din AND2=== &lt;br /&gt;
&lt;br /&gt;
Acest exercitiu arata cum se construieste o poarta AND cu 4 intrari din porti AND mai simple, cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca toate intrarile sunt &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_and4.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: OR4 din OR2===&lt;br /&gt;
&lt;br /&gt;
Asemanator cu exercitiul anterior, se poate construi si o poarta or cu 4 intrari din porti or cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca oricare din intrari (cel putin una) este &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_or4_din_or2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: AND4 din AND2 aranjat in cascada (nu arbore)===&lt;br /&gt;
&lt;br /&gt;
In multe cazuri, aceeasi functionalitate poate fi atinsa prin circuite care arata diferit. &lt;br /&gt;
O alta varianta de a face o poarta AND cu 4 intrari este prezentata mai jos. &lt;br /&gt;
&lt;br /&gt;
Comparati cele 2 variante. &lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2_v2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: AND4 din NAND2===&lt;br /&gt;
&lt;br /&gt;
Orice poarta logica de baza poate fi construita doar din porti NAND sau doar din porti NOR. &lt;br /&gt;
&lt;br /&gt;
Desenati si implementati circuitul pentru o poarta AND4 din porti NAND cu 2 intrari. &lt;br /&gt;
&lt;br /&gt;
Tip: Incercati intai sa generati o poarta AND2 din NAND2.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: AND4 pe 4b din AND4 pe 1b===&lt;br /&gt;
&lt;br /&gt;
Se pot face operatii logice si pe mai multi biti deodata prin punerea in paralel a mai multor porti cu o singura iesire.&lt;br /&gt;
	Exemplu :&lt;br /&gt;
		pentru intrarile 0011 si 1110 iesirea va fi 0010&lt;br /&gt;
&lt;br /&gt;
Pentru exersarea instantierii si intelegerea circuitului din spatele operatilor multibit implementati acest circuit prin instantierea a 4 porti AND4 pe 1 bit intr-o poarta AND4 pe 4 biti.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v1.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns):&lt;br /&gt;
 &lt;br /&gt;
[[Fișier:Wavedrom_and4_4b.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
Exista si un mod mai rapid si simplu de a scrie aceasta functionalitate, grupand intrarile si iesirile in &amp;quot;bus&amp;quot;-uri, ca in codul de mai jos.&lt;br /&gt;
Acest mod de a grupa firele este desenat mai jos.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Fisierul and4_4b.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and4_4b&lt;br /&gt;
	(&lt;br /&gt;
		input logic [3:0] in0,	// in0 are 4b, de la bit 3 la bit 0 inclusiv &lt;br /&gt;
		input logic [3:0] in1,	// se noteaza msb:lsb (most significant bit: least significant bit) (echivalent cu conceptul de cifra sutelor, cifra unitatilor, pt binar)&lt;br /&gt;
		input logic [3:0] in2,&lt;br /&gt;
		input logic [3:0] in3,&lt;br /&gt;
		output logic [3:0] out0&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
assign out0 = in0 &amp;amp; in1 &amp;amp; in2 &amp;amp; in3;&lt;br /&gt;
	&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Desenati schemele logice pentru urmatoarele circuite:===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;a) Schema 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema1 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f, g;&lt;br /&gt;
	&lt;br /&gt;
	logic w1;&lt;br /&gt;
	logic w2;&lt;br /&gt;
	&lt;br /&gt;
	and P1 ( w1, a, c );&lt;br /&gt;
	or P2 ( f, w1, w2, d);&lt;br /&gt;
	not P3 (w2, b);&lt;br /&gt;
	and P4 (g, w1, b, d);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observatie: In versiunea veche de verilog (si s-a pastrat si in cea curenta), se pot specifica directiile porturilor si in exteriorul parantezelor, ca mai sus. &lt;br /&gt;
Aceasta scriere NU este recomandata. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;b) Schema 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema2 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f;&lt;br /&gt;
	&lt;br /&gt;
	logic w1, w2;&lt;br /&gt;
	&lt;br /&gt;
	nand P1 ( w1, a, b ), P2 (w2, c, d);&lt;br /&gt;
	and P3 ( f, w1, w2);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; asemanator cu C/C++, se pot face declaratii in aceeasi linie a mai multor &amp;quot;variabile&amp;quot;, aici fire sau instante, cum se poate vedea la w1 si w2 (ambele fiind fire) sau la P1 si P2 (ambele fiind porti nand).&lt;br /&gt;
Aceasta scriere NU este recomandata.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_1_:_Generare_de_forme_de_unda&amp;diff=8277</id>
		<title>CID aplicatii 1 : Generare de forme de unda</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_1_:_Generare_de_forme_de_unda&amp;diff=8277"/>
		<updated>2026-02-28T17:42:01Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exercițiul 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;În această sesiune de aplicații vom învăța cum să generăm semnale digitale cu ajutorul limbajului SystemVerilog. Generarea de semnale este utilizată în testarea prin simulare a circuitelor digitale. Semnalele generate sunt introduse la intrarea circuitului, observându-se apoi cum se modifică starea ieșirilor acestuia.&lt;br /&gt;
&lt;br /&gt;
Proiectarea circuitelor digitale se bazează pe generarea unor circuite digitale fizice. Deși se va scrie cod în limbajul SystemVerilog, mereu trebuie avut în vedere faptul că în spate se va genera un circuit fizic, codul nu se rulează pas cu pas, aceasta fiind deosebirea fundamentală dintre limbajele de descriere hardware (generează circuite fizice) și limbajele de programare (cod care se execută pas cu pas). Unele concepte cât și unele elemente de sintaxa este posibil să semene cu ce ați facut la programare, dar este important să  înțelegeți că prin codul scris se desenează/generează circuite. Sau invers, pornind de la un desen, se poate face o descriere în SystemVerilog a acestuia.&lt;br /&gt;
&lt;br /&gt;
Proiectele exemplu care pot fi descărcate au fost implementate folosind Vivado 2021.2. Dacă aveți altă versiune este posibil să vă ceară să le salvați în versiunea respectivă sau să fie nevoie să vă faceți un proiect nou, în care să adaugați fișierele cu cod.&lt;br /&gt;
&lt;br /&gt;
==Noțiuni și cunoștințe necesare==&lt;br /&gt;
 &lt;br /&gt;
* [[Introducere. SystemVerilog HDL]] (Sintaxa [[SystemVerilog]])&lt;br /&gt;
&lt;br /&gt;
* [[Tutorial Vivado]].&lt;br /&gt;
&lt;br /&gt;
==Modulul de test (Testbench)==&lt;br /&gt;
Modulul de test este un modul nesintetizabil (nu poate fi transformat într-un circuit de către utilitarul care realizează sinteza) și este folosit, așa cum sugerează și numele, în testarea circuitelor. Acest modul este folosit exclusiv în simulare. Simularea permite detecția rapidă a erorilor de implementare și corectarea acestora. Ideea generală a unui modul de test este descrisă în figura de mai jos (considerăm un circuit cu numele &amp;#039;&amp;#039;circuit&amp;#039;&amp;#039; și modulul său de test &amp;#039;&amp;#039;circuit_tb&amp;#039;&amp;#039;):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CircuitTestbench.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
După cum se vede în figura de mai sus, modulul de test conține printre altele și un &amp;#039;&amp;#039;&amp;#039;generator de semnale de test&amp;#039;&amp;#039;&amp;#039;. Acesta are rolul de a genera câte un semnal de test pentru fiecare intrare a circuitului. Forma acestor semnale de test este stabilită de către cel care realizează verificarea și trebuie aleasă astfel încât să detectăm cât mai multe posibile erori.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
====Exemplul 1: Generarea a doua semnale digitale de 1 bit====&lt;br /&gt;
Să se genereze două semnale digitale de 1 bit, care să aibă următoarea variație în timp (unitatea de timp este de 1ns):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CID Aplicatii1 ex1.svg|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     // setăm unitatea de timp la 1ns, cu o precizie de 1ps&lt;br /&gt;
&lt;br /&gt;
module waveform1();    // modulul se numește waveform1 și nu are nicio intrare și nicio ieșire. Semnalele de test generate sunt semnale interne.&lt;br /&gt;
&lt;br /&gt;
logic a, b;              // cele două semnale de test sunt trebuie declarate ca elemente de tip logic.&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    $monitor(&amp;quot;time = %2d, a = %b, b=%b&amp;quot;, $time, a, b);  // monitorizăm în consolă starea semnalelor a si b&lt;br /&gt;
       a = 0;          // semnalul a va avea valoarea 0 la momentul inițial de timp (la momentul t = 0)&lt;br /&gt;
       b = 0;          // semnalul b va avea valoarea 0 la momentul inițial de timp (la momentul t = 0)&lt;br /&gt;
    #1 a = 1;          // după 1ns de la momentul inițial, a se face 1&lt;br /&gt;
    #1 b = 1;          // după 2ns de la momentul inițial, b se face 1&lt;br /&gt;
    #1 a = 0;          // după 3ns de la momentul inițial, a se face 0&lt;br /&gt;
       b = 0;          // după 3ns de la momentul inițial, b se face 0&lt;br /&gt;
    #2 $stop();        // simularea este oprită&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule              // incheiem descrierea modulului de generare de semnale digitale&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Atunci când un semnal are dimensiunea de 1 bit, nu va apărea nimic intre tipul acestuia și nume. Atunci când semnalul are o dimensiune mai mare sau egală cu doi biți, dimensiunea va fi descrisă sub forma &amp;#039;&amp;#039;&amp;#039;[n-1:0]&amp;#039;&amp;#039;&amp;#039;, unde &amp;#039;&amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;#039; este numărul de biți. Conform acestei descrieri, bitul &amp;#039;&amp;#039;&amp;#039;n-1&amp;#039;&amp;#039;&amp;#039; este cel mai semnificativ.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
logic a;           //semnal cu dimeniunea de 1 bit&lt;br /&gt;
logic [7:0] data;  //semnal/magistrală/bus cu dimensiunea de 8 biți&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Exemplul 2: Generarea unui semnal periodic de 1 bit====&lt;br /&gt;
Să se genereze un semnal digital periodic de 1 bit, cu perioada egală cu 2ns:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Clock wave.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     // setăm unitatea de timp la 1ns, cu o precizie de 1ps&lt;br /&gt;
&lt;br /&gt;
module waveform2();    // modulul se numește waveform2 si nu are nicio intrare și nicio iesire&lt;br /&gt;
&lt;br /&gt;
logic clock;             // semnalul de test este declarat de tip logic&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock = 0;              // valoarea inițială a semnalului va fi 0 (la momentul t = 0)&lt;br /&gt;
    forever                 // forever indică faptul că ce urmează se va repeta într-o buclă continuă. &lt;br /&gt;
    begin&lt;br /&gt;
        #1 clock = ~clock;  // La trecea unui timp egal cu unitatea de timp definită, semnalul clock iși va nega valoarea                         &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
   // fiind o singura instructiune in bucla &amp;quot;forever&amp;quot;, se putea omite begin/end =&amp;gt; forever #1 clock = ~clock; &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    #20 $stop();       // La 20 de unități de timp (aici, 20 ns), simularea se va opri. &lt;br /&gt;
                       // Aici punem $stop într-un bloc separat, deoarece forever blochează blocul initial în care se află&lt;br /&gt;
                       // Toate blocurile initial încep la același moment de timp (t = 0) și au efect în paralel&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;
==Exerciții==&lt;br /&gt;
====Exercițiul 1====&lt;br /&gt;
Generați două semnale digitale &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; de 1 bit, astfel încât să se formeze cu ele toate cele 4 combinații posibile, după cum urmează:&lt;br /&gt;
&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 0ns&amp;#039;&amp;#039;&amp;#039;: a = 0, b = 0&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 1ns&amp;#039;&amp;#039;&amp;#039;: a = 0, b = 1&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 2ns&amp;#039;&amp;#039;&amp;#039;: a = 1, b = 0&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 3ns&amp;#039;&amp;#039;&amp;#039;: a = 1, b = 1&lt;br /&gt;
&lt;br /&gt;
Rezolvati aceasta cerinta folosind un singur block &amp;quot;initial&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Rezolvati aceasta cerinta folosind blocuri &amp;quot;initial&amp;quot; distincte pentru fiecare din cele 2 semnale si pentru comanda de &amp;quot;stop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 2====&lt;br /&gt;
Generați semnalele din imaginea de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:lab1_ex2_waveform.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
Simularea se va opri la 100ns de la inceperea ei.&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 3====&lt;br /&gt;
Să se genereze un semnal digital de 8 biți aliniat la fronturile crescătoare ale unui semnal periodic (semnal de ceas), ce are perioada de 2ns:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Clock and data wave.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Frontul crescător al unui semnal este definit ca tranziția dintre nivelul de 0 logic și 1 logic.&lt;br /&gt;
* Spunem că un semnal este aliniat la fronturile crescătoare ale unui alt semnal dacă acesta își modifică valoarea imediat după apariția acelui front crescător. În figura de mai sus, se observă că &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; își schimbă valoarea imediat după fiecare front crescător al semnalului &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Indicații&amp;#039;&amp;#039;&amp;#039;: &lt;br /&gt;
&lt;br /&gt;
* Așteptarea unui front crescător al semnalului &amp;#039;&amp;#039;NumeSemnal&amp;#039;&amp;#039; se realizează cu &amp;#039;&amp;#039;&amp;#039;@(posedge &amp;#039;&amp;#039;NumeSemnal&amp;#039;&amp;#039;)&amp;#039;&amp;#039;&amp;#039;. Aceasta va înlocui întârzierile de tip &amp;#039;&amp;#039;&amp;#039;#n&amp;#039;&amp;#039;&amp;#039; folosite anterior.&lt;br /&gt;
* Pentru semnalele ce se doresc aliniate la un eveniment de tip &amp;#039;&amp;#039;&amp;#039;posedge&amp;#039;&amp;#039;&amp;#039;, vom folosi atribuirea non-blocantă: de exemplu, &amp;#039;&amp;#039;&amp;#039;data &amp;lt;= 1;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* Nu uitați! Folosirea &amp;#039;&amp;#039;forever&amp;#039;&amp;#039; pentru generarea semnalului de ceas va bloca acel bloc &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;.&lt;br /&gt;
* Incrementarea valorii unui semnal se poate realiza cu un bloc de tip &amp;#039;&amp;#039;for&amp;#039;&amp;#039;, inclus in blocul &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;. Blocul &amp;#039;&amp;#039;for&amp;#039;&amp;#039; va avea nevoie de un contor de tip &amp;#039;&amp;#039;integer&amp;#039;&amp;#039;, declarat în afara blocului &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;. Pentru mai multe detalii, consultați tutorialul de sintaxa SystemVerilog.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Folosind indicațiile anterioare, înlocuiți al doilea bloc &amp;#039;&amp;#039;initial&amp;#039;&amp;#039; din &amp;#039;&amp;#039;&amp;#039;Exemplul 2&amp;#039;&amp;#039;&amp;#039; cu următoarea secvență și completați liniile de cod lipsă:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
integer index;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    for(index = 0; index &amp;lt; 11; index = index + 1) begin&lt;br /&gt;
        //completati codul    &lt;br /&gt;
    end&lt;br /&gt;
    #20 $stop();&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 4====&lt;br /&gt;
Desenați formele de undă ale semnalelor de test &amp;#039;&amp;#039;a&amp;#039;&amp;#039;, &amp;#039;&amp;#039;b&amp;#039;&amp;#039; și &amp;#039;&amp;#039;c&amp;#039;&amp;#039;, generate cu ajutorul următoarelor două blocuri &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     &lt;br /&gt;
&lt;br /&gt;
module waveform();    &lt;br /&gt;
&lt;br /&gt;
logic a, b, c; &lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       a = 0;          &lt;br /&gt;
       b = 0;          &lt;br /&gt;
    #2 b = 1;          &lt;br /&gt;
    #1 a = 1;          &lt;br /&gt;
    #3 b = 0;          &lt;br /&gt;
    #3 a = 0;          &lt;br /&gt;
    #2 $stop();       &lt;br /&gt;
end   &lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       c = 1;                   &lt;br /&gt;
    #2 c = 0;          &lt;br /&gt;
    #3 c = 1;                &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;
====Exercițiul 5====&lt;br /&gt;
Generati un semnal digital &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039; cu dimensiunea de 1 bit si perioada de 2ns si un semnal digital &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039;, cu dimensiunea de 4 biti, aliniat la fronturile crescatoare ale semnalului &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039;. Semnalul &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; va varia astfel: &amp;#039;&amp;#039;&amp;#039;0, 1, 2, 3, 0, 1, 2 ,3, 0, 1 ... &amp;#039;&amp;#039;&amp;#039;. Opriti simularea dupa ce semnalul &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; a realizat 4 variatii complete (s-a generat secventa &amp;#039;&amp;#039;&amp;#039;0, 1, 2, 3&amp;#039;&amp;#039;&amp;#039; de 4 ori).&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Lab1_ex2_waveform.png&amp;diff=8276</id>
		<title>Fișier:Lab1 ex2 waveform.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Lab1_ex2_waveform.png&amp;diff=8276"/>
		<updated>2026-02-28T17:41:09Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_1_:_Generare_de_forme_de_unda&amp;diff=8275</id>
		<title>CID aplicatii 1 : Generare de forme de unda</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_1_:_Generare_de_forme_de_unda&amp;diff=8275"/>
		<updated>2026-02-28T17:40:32Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;În această sesiune de aplicații vom învăța cum să generăm semnale digitale cu ajutorul limbajului SystemVerilog. Generarea de semnale este utilizată în testarea prin simulare a circuitelor digitale. Semnalele generate sunt introduse la intrarea circuitului, observându-se apoi cum se modifică starea ieșirilor acestuia.&lt;br /&gt;
&lt;br /&gt;
Proiectarea circuitelor digitale se bazează pe generarea unor circuite digitale fizice. Deși se va scrie cod în limbajul SystemVerilog, mereu trebuie avut în vedere faptul că în spate se va genera un circuit fizic, codul nu se rulează pas cu pas, aceasta fiind deosebirea fundamentală dintre limbajele de descriere hardware (generează circuite fizice) și limbajele de programare (cod care se execută pas cu pas). Unele concepte cât și unele elemente de sintaxa este posibil să semene cu ce ați facut la programare, dar este important să  înțelegeți că prin codul scris se desenează/generează circuite. Sau invers, pornind de la un desen, se poate face o descriere în SystemVerilog a acestuia.&lt;br /&gt;
&lt;br /&gt;
Proiectele exemplu care pot fi descărcate au fost implementate folosind Vivado 2021.2. Dacă aveți altă versiune este posibil să vă ceară să le salvați în versiunea respectivă sau să fie nevoie să vă faceți un proiect nou, în care să adaugați fișierele cu cod.&lt;br /&gt;
&lt;br /&gt;
==Noțiuni și cunoștințe necesare==&lt;br /&gt;
 &lt;br /&gt;
* [[Introducere. SystemVerilog HDL]] (Sintaxa [[SystemVerilog]])&lt;br /&gt;
&lt;br /&gt;
* [[Tutorial Vivado]].&lt;br /&gt;
&lt;br /&gt;
==Modulul de test (Testbench)==&lt;br /&gt;
Modulul de test este un modul nesintetizabil (nu poate fi transformat într-un circuit de către utilitarul care realizează sinteza) și este folosit, așa cum sugerează și numele, în testarea circuitelor. Acest modul este folosit exclusiv în simulare. Simularea permite detecția rapidă a erorilor de implementare și corectarea acestora. Ideea generală a unui modul de test este descrisă în figura de mai jos (considerăm un circuit cu numele &amp;#039;&amp;#039;circuit&amp;#039;&amp;#039; și modulul său de test &amp;#039;&amp;#039;circuit_tb&amp;#039;&amp;#039;):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CircuitTestbench.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
După cum se vede în figura de mai sus, modulul de test conține printre altele și un &amp;#039;&amp;#039;&amp;#039;generator de semnale de test&amp;#039;&amp;#039;&amp;#039;. Acesta are rolul de a genera câte un semnal de test pentru fiecare intrare a circuitului. Forma acestor semnale de test este stabilită de către cel care realizează verificarea și trebuie aleasă astfel încât să detectăm cât mai multe posibile erori.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
====Exemplul 1: Generarea a doua semnale digitale de 1 bit====&lt;br /&gt;
Să se genereze două semnale digitale de 1 bit, care să aibă următoarea variație în timp (unitatea de timp este de 1ns):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CID Aplicatii1 ex1.svg|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     // setăm unitatea de timp la 1ns, cu o precizie de 1ps&lt;br /&gt;
&lt;br /&gt;
module waveform1();    // modulul se numește waveform1 și nu are nicio intrare și nicio ieșire. Semnalele de test generate sunt semnale interne.&lt;br /&gt;
&lt;br /&gt;
logic a, b;              // cele două semnale de test sunt trebuie declarate ca elemente de tip logic.&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    $monitor(&amp;quot;time = %2d, a = %b, b=%b&amp;quot;, $time, a, b);  // monitorizăm în consolă starea semnalelor a si b&lt;br /&gt;
       a = 0;          // semnalul a va avea valoarea 0 la momentul inițial de timp (la momentul t = 0)&lt;br /&gt;
       b = 0;          // semnalul b va avea valoarea 0 la momentul inițial de timp (la momentul t = 0)&lt;br /&gt;
    #1 a = 1;          // după 1ns de la momentul inițial, a se face 1&lt;br /&gt;
    #1 b = 1;          // după 2ns de la momentul inițial, b se face 1&lt;br /&gt;
    #1 a = 0;          // după 3ns de la momentul inițial, a se face 0&lt;br /&gt;
       b = 0;          // după 3ns de la momentul inițial, b se face 0&lt;br /&gt;
    #2 $stop();        // simularea este oprită&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule              // incheiem descrierea modulului de generare de semnale digitale&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Atunci când un semnal are dimensiunea de 1 bit, nu va apărea nimic intre tipul acestuia și nume. Atunci când semnalul are o dimensiune mai mare sau egală cu doi biți, dimensiunea va fi descrisă sub forma &amp;#039;&amp;#039;&amp;#039;[n-1:0]&amp;#039;&amp;#039;&amp;#039;, unde &amp;#039;&amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;#039; este numărul de biți. Conform acestei descrieri, bitul &amp;#039;&amp;#039;&amp;#039;n-1&amp;#039;&amp;#039;&amp;#039; este cel mai semnificativ.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
logic a;           //semnal cu dimeniunea de 1 bit&lt;br /&gt;
logic [7:0] data;  //semnal/magistrală/bus cu dimensiunea de 8 biți&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Exemplul 2: Generarea unui semnal periodic de 1 bit====&lt;br /&gt;
Să se genereze un semnal digital periodic de 1 bit, cu perioada egală cu 2ns:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Clock wave.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     // setăm unitatea de timp la 1ns, cu o precizie de 1ps&lt;br /&gt;
&lt;br /&gt;
module waveform2();    // modulul se numește waveform2 si nu are nicio intrare și nicio iesire&lt;br /&gt;
&lt;br /&gt;
logic clock;             // semnalul de test este declarat de tip logic&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock = 0;              // valoarea inițială a semnalului va fi 0 (la momentul t = 0)&lt;br /&gt;
    forever                 // forever indică faptul că ce urmează se va repeta într-o buclă continuă. &lt;br /&gt;
    begin&lt;br /&gt;
        #1 clock = ~clock;  // La trecea unui timp egal cu unitatea de timp definită, semnalul clock iși va nega valoarea                         &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
   // fiind o singura instructiune in bucla &amp;quot;forever&amp;quot;, se putea omite begin/end =&amp;gt; forever #1 clock = ~clock; &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    #20 $stop();       // La 20 de unități de timp (aici, 20 ns), simularea se va opri. &lt;br /&gt;
                       // Aici punem $stop într-un bloc separat, deoarece forever blochează blocul initial în care se află&lt;br /&gt;
                       // Toate blocurile initial încep la același moment de timp (t = 0) și au efect în paralel&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;
==Exerciții==&lt;br /&gt;
====Exercițiul 1====&lt;br /&gt;
Generați două semnale digitale &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; de 1 bit, astfel încât să se formeze cu ele toate cele 4 combinații posibile, după cum urmează:&lt;br /&gt;
&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 0ns&amp;#039;&amp;#039;&amp;#039;: a = 0, b = 0&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 1ns&amp;#039;&amp;#039;&amp;#039;: a = 0, b = 1&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 2ns&amp;#039;&amp;#039;&amp;#039;: a = 1, b = 0&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 3ns&amp;#039;&amp;#039;&amp;#039;: a = 1, b = 1&lt;br /&gt;
&lt;br /&gt;
Rezolvati aceasta cerinta folosind un singur block &amp;quot;initial&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Rezolvati aceasta cerinta folosind blocuri &amp;quot;initial&amp;quot; distincte pentru fiecare din cele 2 semnale si pentru comanda de &amp;quot;stop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 2====&lt;br /&gt;
Generați semnalele din imaginea de mai jos:&lt;br /&gt;
[[Fișier:lab1_ex2_waveform.png | 600px]]&lt;br /&gt;
Simularea se va opri la 100ns de la inceperea ei.&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 3====&lt;br /&gt;
Să se genereze un semnal digital de 8 biți aliniat la fronturile crescătoare ale unui semnal periodic (semnal de ceas), ce are perioada de 2ns:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Clock and data wave.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Frontul crescător al unui semnal este definit ca tranziția dintre nivelul de 0 logic și 1 logic.&lt;br /&gt;
* Spunem că un semnal este aliniat la fronturile crescătoare ale unui alt semnal dacă acesta își modifică valoarea imediat după apariția acelui front crescător. În figura de mai sus, se observă că &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; își schimbă valoarea imediat după fiecare front crescător al semnalului &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Indicații&amp;#039;&amp;#039;&amp;#039;: &lt;br /&gt;
&lt;br /&gt;
* Așteptarea unui front crescător al semnalului &amp;#039;&amp;#039;NumeSemnal&amp;#039;&amp;#039; se realizează cu &amp;#039;&amp;#039;&amp;#039;@(posedge &amp;#039;&amp;#039;NumeSemnal&amp;#039;&amp;#039;)&amp;#039;&amp;#039;&amp;#039;. Aceasta va înlocui întârzierile de tip &amp;#039;&amp;#039;&amp;#039;#n&amp;#039;&amp;#039;&amp;#039; folosite anterior.&lt;br /&gt;
* Pentru semnalele ce se doresc aliniate la un eveniment de tip &amp;#039;&amp;#039;&amp;#039;posedge&amp;#039;&amp;#039;&amp;#039;, vom folosi atribuirea non-blocantă: de exemplu, &amp;#039;&amp;#039;&amp;#039;data &amp;lt;= 1;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* Nu uitați! Folosirea &amp;#039;&amp;#039;forever&amp;#039;&amp;#039; pentru generarea semnalului de ceas va bloca acel bloc &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;.&lt;br /&gt;
* Incrementarea valorii unui semnal se poate realiza cu un bloc de tip &amp;#039;&amp;#039;for&amp;#039;&amp;#039;, inclus in blocul &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;. Blocul &amp;#039;&amp;#039;for&amp;#039;&amp;#039; va avea nevoie de un contor de tip &amp;#039;&amp;#039;integer&amp;#039;&amp;#039;, declarat în afara blocului &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;. Pentru mai multe detalii, consultați tutorialul de sintaxa SystemVerilog.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Folosind indicațiile anterioare, înlocuiți al doilea bloc &amp;#039;&amp;#039;initial&amp;#039;&amp;#039; din &amp;#039;&amp;#039;&amp;#039;Exemplul 2&amp;#039;&amp;#039;&amp;#039; cu următoarea secvență și completați liniile de cod lipsă:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
integer index;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    for(index = 0; index &amp;lt; 11; index = index + 1) begin&lt;br /&gt;
        //completati codul    &lt;br /&gt;
    end&lt;br /&gt;
    #20 $stop();&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 4====&lt;br /&gt;
Desenați formele de undă ale semnalelor de test &amp;#039;&amp;#039;a&amp;#039;&amp;#039;, &amp;#039;&amp;#039;b&amp;#039;&amp;#039; și &amp;#039;&amp;#039;c&amp;#039;&amp;#039;, generate cu ajutorul următoarelor două blocuri &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     &lt;br /&gt;
&lt;br /&gt;
module waveform();    &lt;br /&gt;
&lt;br /&gt;
logic a, b, c; &lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       a = 0;          &lt;br /&gt;
       b = 0;          &lt;br /&gt;
    #2 b = 1;          &lt;br /&gt;
    #1 a = 1;          &lt;br /&gt;
    #3 b = 0;          &lt;br /&gt;
    #3 a = 0;          &lt;br /&gt;
    #2 $stop();       &lt;br /&gt;
end   &lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       c = 1;                   &lt;br /&gt;
    #2 c = 0;          &lt;br /&gt;
    #3 c = 1;                &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;
====Exercițiul 5====&lt;br /&gt;
Generati un semnal digital &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039; cu dimensiunea de 1 bit si perioada de 2ns si un semnal digital &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039;, cu dimensiunea de 4 biti, aliniat la fronturile crescatoare ale semnalului &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039;. Semnalul &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; va varia astfel: &amp;#039;&amp;#039;&amp;#039;0, 1, 2, 3, 0, 1, 2 ,3, 0, 1 ... &amp;#039;&amp;#039;&amp;#039;. Opriti simularea dupa ce semnalul &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; a realizat 4 variatii complete (s-a generat secventa &amp;#039;&amp;#039;&amp;#039;0, 1, 2, 3&amp;#039;&amp;#039;&amp;#039; de 4 ori).&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_1_:_Generare_de_forme_de_unda&amp;diff=8274</id>
		<title>CID aplicatii 1 : Generare de forme de unda</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_1_:_Generare_de_forme_de_unda&amp;diff=8274"/>
		<updated>2026-02-28T17:29:46Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exercițiul 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;În această sesiune de aplicații vom învăța cum să generăm semnale digitale cu ajutorul limbajului SystemVerilog. Generarea de semnale este utilizată în testarea prin simulare a circuitelor digitale. Semnalele generate sunt introduse la intrarea circuitului, observându-se apoi cum se modifică starea ieșirilor acestuia.&lt;br /&gt;
&lt;br /&gt;
Proiectarea circuitelor digitale se bazează pe generarea unor circuite digitale fizice. Deși se va scrie cod în limbajul SystemVerilog, mereu trebuie avut în vedere faptul că în spate se va genera un circuit fizic, codul nu se rulează pas cu pas, aceasta fiind deosebirea fundamentală dintre limbajele de descriere hardware (generează circuite fizice) și limbajele de programare (cod care se execută pas cu pas). Unele concepte cât și unele elemente de sintaxa este posibil să semene cu ce ați facut la programare, dar este important să  înțelegeți că prin codul scris se desenează/generează circuite. Sau invers, pornind de la un desen, se poate face o descriere în SystemVerilog a acestuia.&lt;br /&gt;
&lt;br /&gt;
Proiectele exemplu care pot fi descărcate au fost implementate folosind Vivado 2021.2. Dacă aveți altă versiune este posibil să vă ceară să le salvați în versiunea respectivă sau să fie nevoie să vă faceți un proiect nou, în care să adaugați fișierele cu cod.&lt;br /&gt;
&lt;br /&gt;
==Noțiuni și cunoștințe necesare==&lt;br /&gt;
 &lt;br /&gt;
* [[Introducere. SystemVerilog HDL]] (Sintaxa [[SystemVerilog]])&lt;br /&gt;
&lt;br /&gt;
* [[Tutorial Vivado]].&lt;br /&gt;
&lt;br /&gt;
==Modulul de test (Testbench)==&lt;br /&gt;
Modulul de test este un modul nesintetizabil (nu poate fi transformat într-un circuit de către utilitarul care realizează sinteza) și este folosit, așa cum sugerează și numele, în testarea circuitelor. Acest modul este folosit exclusiv în simulare. Simularea permite detecția rapidă a erorilor de implementare și corectarea acestora. Ideea generală a unui modul de test este descrisă în figura de mai jos (considerăm un circuit cu numele &amp;#039;&amp;#039;circuit&amp;#039;&amp;#039; și modulul său de test &amp;#039;&amp;#039;circuit_tb&amp;#039;&amp;#039;):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CircuitTestbench.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
După cum se vede în figura de mai sus, modulul de test conține printre altele și un &amp;#039;&amp;#039;&amp;#039;generator de semnale de test&amp;#039;&amp;#039;&amp;#039;. Acesta are rolul de a genera câte un semnal de test pentru fiecare intrare a circuitului. Forma acestor semnale de test este stabilită de către cel care realizează verificarea și trebuie aleasă astfel încât să detectăm cât mai multe posibile erori.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
====Exemplul 1: Generarea a doua semnale digitale de 1 bit====&lt;br /&gt;
Să se genereze două semnale digitale de 1 bit, care să aibă următoarea variație în timp (unitatea de timp este de 1ns):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CID Aplicatii1 ex1.svg|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     // setăm unitatea de timp la 1ns, cu o precizie de 1ps&lt;br /&gt;
&lt;br /&gt;
module waveform1();    // modulul se numește waveform1 și nu are nicio intrare și nicio ieșire. Semnalele de test generate sunt semnale interne.&lt;br /&gt;
&lt;br /&gt;
logic a, b;              // cele două semnale de test sunt trebuie declarate ca elemente de tip logic.&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    $monitor(&amp;quot;time = %2d, a = %b, b=%b&amp;quot;, $time, a, b);  // monitorizăm în consolă starea semnalelor a si b&lt;br /&gt;
       a = 0;          // semnalul a va avea valoarea 0 la momentul inițial de timp (la momentul t = 0)&lt;br /&gt;
       b = 0;          // semnalul b va avea valoarea 0 la momentul inițial de timp (la momentul t = 0)&lt;br /&gt;
    #1 a = 1;          // după 1ns de la momentul inițial, a se face 1&lt;br /&gt;
    #1 b = 1;          // după 2ns de la momentul inițial, b se face 1&lt;br /&gt;
    #1 a = 0;          // după 3ns de la momentul inițial, a se face 0&lt;br /&gt;
       b = 0;          // după 3ns de la momentul inițial, b se face 0&lt;br /&gt;
    #2 $stop();        // simularea este oprită&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule              // incheiem descrierea modulului de generare de semnale digitale&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Atunci când un semnal are dimensiunea de 1 bit, nu va apărea nimic intre tipul acestuia și nume. Atunci când semnalul are o dimensiune mai mare sau egală cu doi biți, dimensiunea va fi descrisă sub forma &amp;#039;&amp;#039;&amp;#039;[n-1:0]&amp;#039;&amp;#039;&amp;#039;, unde &amp;#039;&amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;#039; este numărul de biți. Conform acestei descrieri, bitul &amp;#039;&amp;#039;&amp;#039;n-1&amp;#039;&amp;#039;&amp;#039; este cel mai semnificativ.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
logic a;           //semnal cu dimeniunea de 1 bit&lt;br /&gt;
logic [7:0] data;  //semnal/magistrală/bus cu dimensiunea de 8 biți&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Exemplul 2: Generarea unui semnal periodic de 1 bit====&lt;br /&gt;
Să se genereze un semnal digital periodic de 1 bit, cu perioada egală cu 2ns:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Clock wave.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     // setăm unitatea de timp la 1ns, cu o precizie de 1ps&lt;br /&gt;
&lt;br /&gt;
module waveform2();    // modulul se numește waveform2 si nu are nicio intrare și nicio iesire&lt;br /&gt;
&lt;br /&gt;
logic clock;             // semnalul de test este declarat de tip logic&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock = 0;              // valoarea inițială a semnalului va fi 0 (la momentul t = 0)&lt;br /&gt;
    forever                 // forever indică faptul că ce urmează se va repeta într-o buclă continuă. &lt;br /&gt;
    begin&lt;br /&gt;
        #1 clock = ~clock;  // La trecea unui timp egal cu unitatea de timp definită, semnalul clock iși va nega valoarea                         &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
   // fiind o singura instructiune in bucla &amp;quot;forever&amp;quot;, se putea omite begin/end =&amp;gt; forever #1 clock = ~clock; &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    #20 $stop();       // La 20 de unități de timp (aici, 20 ns), simularea se va opri. &lt;br /&gt;
                       // Aici punem $stop într-un bloc separat, deoarece forever blochează blocul initial în care se află&lt;br /&gt;
                       // Toate blocurile initial încep la același moment de timp (t = 0) și au efect în paralel&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;
==Exerciții==&lt;br /&gt;
====Exercițiul 1====&lt;br /&gt;
Generați două semnale digitale &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; de 1 bit, astfel încât să se formeze cu ele toate cele 4 combinații posibile, după cum urmează:&lt;br /&gt;
&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 0ns&amp;#039;&amp;#039;&amp;#039;: a = 0, b = 0&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 1ns&amp;#039;&amp;#039;&amp;#039;: a = 0, b = 1&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 2ns&amp;#039;&amp;#039;&amp;#039;: a = 1, b = 0&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 3ns&amp;#039;&amp;#039;&amp;#039;: a = 1, b = 1&lt;br /&gt;
&lt;br /&gt;
Rezolvati aceasta cerinta folosind un singur block &amp;quot;initial&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Rezolvati aceasta cerinta folosind blocuri &amp;quot;initial&amp;quot; distincte pentru fiecare din cele 2 semnale si pentru comanda de &amp;quot;stop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 2====&lt;br /&gt;
Să se genereze un semnal digital de 8 biți aliniat la fronturile crescătoare ale unui semnal periodic (semnal de ceas), ce are perioada de 2ns:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Clock and data wave.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Frontul crescător al unui semnal este definit ca tranziția dintre nivelul de 0 logic și 1 logic.&lt;br /&gt;
* Spunem că un semnal este aliniat la fronturile crescătoare ale unui alt semnal dacă acesta își modifică valoarea imediat după apariția acelui front crescător. În figura de mai sus, se observă că &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; își schimbă valoarea imediat după fiecare front crescător al semnalului &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Indicații&amp;#039;&amp;#039;&amp;#039;: &lt;br /&gt;
&lt;br /&gt;
* Așteptarea unui front crescător al semnalului &amp;#039;&amp;#039;NumeSemnal&amp;#039;&amp;#039; se realizează cu &amp;#039;&amp;#039;&amp;#039;@(posedge &amp;#039;&amp;#039;NumeSemnal&amp;#039;&amp;#039;)&amp;#039;&amp;#039;&amp;#039;. Aceasta va înlocui întârzierile de tip &amp;#039;&amp;#039;&amp;#039;#n&amp;#039;&amp;#039;&amp;#039; folosite anterior.&lt;br /&gt;
* Pentru semnalele ce se doresc aliniate la un eveniment de tip &amp;#039;&amp;#039;&amp;#039;posedge&amp;#039;&amp;#039;&amp;#039;, vom folosi atribuirea non-blocantă: de exemplu, &amp;#039;&amp;#039;&amp;#039;data &amp;lt;= 1;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* Nu uitați! Folosirea &amp;#039;&amp;#039;forever&amp;#039;&amp;#039; pentru generarea semnalului de ceas va bloca acel bloc &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;.&lt;br /&gt;
* Incrementarea valorii unui semnal se poate realiza cu un bloc de tip &amp;#039;&amp;#039;for&amp;#039;&amp;#039;, inclus in blocul &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;. Blocul &amp;#039;&amp;#039;for&amp;#039;&amp;#039; va avea nevoie de un contor de tip &amp;#039;&amp;#039;integer&amp;#039;&amp;#039;, declarat în afara blocului &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;. Pentru mai multe detalii, consultați tutorialul de sintaxa SystemVerilog.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Folosind indicațiile anterioare, înlocuiți al doilea bloc &amp;#039;&amp;#039;initial&amp;#039;&amp;#039; din &amp;#039;&amp;#039;&amp;#039;Exemplul 2&amp;#039;&amp;#039;&amp;#039; cu următoarea secvență și completați liniile de cod lipsă:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
integer index;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    for(index = 0; index &amp;lt; 11; index = index + 1) begin&lt;br /&gt;
        //completati codul    &lt;br /&gt;
    end&lt;br /&gt;
    #20 $stop();&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 3====&lt;br /&gt;
Desenați formele de undă ale semnalelor de test &amp;#039;&amp;#039;a&amp;#039;&amp;#039;, &amp;#039;&amp;#039;b&amp;#039;&amp;#039; și &amp;#039;&amp;#039;c&amp;#039;&amp;#039;, generate cu ajutorul următoarelor două blocuri &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     &lt;br /&gt;
&lt;br /&gt;
module waveform();    &lt;br /&gt;
&lt;br /&gt;
logic a, b, c; &lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       a = 0;          &lt;br /&gt;
       b = 0;          &lt;br /&gt;
    #2 b = 1;          &lt;br /&gt;
    #1 a = 1;          &lt;br /&gt;
    #3 b = 0;          &lt;br /&gt;
    #3 a = 0;          &lt;br /&gt;
    #2 $stop();       &lt;br /&gt;
end   &lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       c = 1;                   &lt;br /&gt;
    #2 c = 0;          &lt;br /&gt;
    #3 c = 1;                &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;
====Exercițiul 4====&lt;br /&gt;
Generati un semnal digital &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039; cu dimensiunea de 1 bit si perioada de 2ns si un semnal digital &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039;, cu dimensiunea de 4 biti, aliniat la fronturile crescatoare ale semnalului &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039;. Semnalul &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; va varia astfel: &amp;#039;&amp;#039;&amp;#039;0, 1, 2, 3, 0, 1, 2 ,3, 0, 1 ... &amp;#039;&amp;#039;&amp;#039;. Opriti simularea dupa ce semnalul &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; a realizat 4 variatii complete (s-a generat secventa &amp;#039;&amp;#039;&amp;#039;0, 1, 2, 3&amp;#039;&amp;#039;&amp;#039; de 4 ori).&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Circuite_Integrate_Digitale&amp;diff=8272</id>
		<title>Circuite Integrate Digitale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Circuite_Integrate_Digitale&amp;diff=8272"/>
		<updated>2026-02-25T19:12:28Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Scopul laboratorului */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Scopul laboratorului ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Laboratorul de circuite integrate digitale vine ca o completare practica a cursului de CID. &lt;br /&gt;
Prin definitie, acesta se va axa pe elemente practice de simulare, sinteza si testare a circuitelor ce sunt prezentate la curs. &lt;br /&gt;
&lt;br /&gt;
Acest laborator se bazeaza pe limbajul &amp;quot;SystemVerilog&amp;quot;, acesta fiind unul din cele 2 limbaje de descriere hardware folosite in industrie la ora actuala (celalalt fiind &amp;quot;VHDL&amp;quot;). &amp;quot;SystemVerilog&amp;quot; vine ca o completare la &amp;quot;Verilog&amp;quot;, introducand numeroase elemente ce ajuta in special testarea circuitelor, dar si unele imbunatatiri pentru procesul de proiectare. &lt;br /&gt;
&lt;br /&gt;
Platformele sunt structurate astfel incat sa contina cateva elemente de teorie minimala, un exemplu de circuit descris in cod Verilog si apoi exercitii pe care sa le rezolvati in ora de aplicatii (simulare/testare pe placa FPGA) si acasa (simulare). &lt;br /&gt;
&lt;br /&gt;
In laborator se va lucra in Vivado, program al firmei Xilinx, pe o placa Boolean Board. &lt;br /&gt;
&lt;br /&gt;
Circuitele digitale sunt o parte fundamentala a electronici moderne, cu numeroase oportunitati in industrie, atat in design cat si in verificarea circuitelor.&lt;br /&gt;
&lt;br /&gt;
Pe langa ce veti invata in acest laborator, limbajul ofera si capabilitati mai avansate pentru a descrie mai eficient circuitele dorite, cat si pentru testarea acestora. Sintaxa nu se termina cu ce invatati aici si pentru cei pasionati, nu ezitati sa va contactati cadrul didactic cu intrebari.&lt;br /&gt;
&lt;br /&gt;
Speram ca o sa va placa, veti invata si vi se va parea interesant ce veti vedea in orele de aplicatii ce urmeaza. Spor.&lt;br /&gt;
&lt;br /&gt;
== Tutoriale și documentații ==&lt;br /&gt;
&lt;br /&gt;
Programul Vivado este gratuit (necesita cont, dar este gratis) si poate fi descarcat si instalat urmand tutorialul de aici:&lt;br /&gt;
# [[Tutorial instalare Vivado]]&lt;br /&gt;
# [[Tutorial Vivado]].&lt;br /&gt;
# [[FPGA - Introducere]].&lt;br /&gt;
# [https://www.realdigital.org/doc/02013cd17602c8af749f00561f88ae21 Boolean Board - user manual]&lt;br /&gt;
# [[Boolean Board - Pinout]].&lt;br /&gt;
# [https://www.tulembedded.com/FPGA/ProductsPYNQ-Z2.html Pynq-Z2 - pagina oficiala]&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;
	&lt;br /&gt;
O lista de link-uri utile poate fi gasita aici:&lt;br /&gt;
# [[Introducere. SystemVerilog HDL]] (Sintaxa [[SystemVerilog]])&lt;br /&gt;
# [https://www.asic-world.com/digital/index.html Asic-world - digital]&lt;br /&gt;
# [https://www.asic-world.com/verilog/index.html Asic-world - verilog]&lt;br /&gt;
# [https://nandgame.com/ Joc online: Nandgame]	&lt;br /&gt;
# [https://circuitverse.org/simulator Simulator/joc online si grafic de circuite: Circuitverse]	&lt;br /&gt;
# [https://falstad.com/circuit/ Simulator online si grafic de circuite (analog+digital): Falstad]&lt;br /&gt;
# [https://github.com/hneemann/Digital Simulator grafic de circuite digitale: hneemann-digital]&lt;br /&gt;
# [https://play.google.com/store/apps/details?id=com.ViacheslavRud.Circuit&amp;amp;hl=en_US&amp;amp;gl=US Joc android - Make it True: Solve the Circuit]&lt;br /&gt;
# [https://www.edaplayground.com/ Simulatoare online (mod text): Edaplayground]&lt;br /&gt;
# [https://wavedrom.com/ Utilitar desenare forme de unda]&lt;br /&gt;
# [https://www.draw.io/ Utilitar desenare diagrame]&lt;br /&gt;
# [[Domenii conexe]]&lt;br /&gt;
&lt;br /&gt;
== Lucrări de laborator ==&lt;br /&gt;
&lt;br /&gt;
# [[CID_aplicatii_1 : Generare de forme de unda]]&lt;br /&gt;
# [[CID_aplicatii_2 : Instantiere si porti logice]]&lt;br /&gt;
# [[CID_aplicatii_3 : Circuite combinationale elementare]]&lt;br /&gt;
# [[CID_aplicatii_4 : Memoria ROM]]&lt;br /&gt;
# [[CID_aplicatii_5 : Exercitii cu circuite combinationale]]&lt;br /&gt;
# CID_aplicatii_6 : Lucrarea 1 - circuite combinationale&lt;br /&gt;
# [[CID_aplicatii_7 : Circuite secventiale elementare]]&lt;br /&gt;
# [[CID_aplicatii_8 : Registre si memorii RAM]]&lt;br /&gt;
# [[CID_aplicatii_9 : Numaratorul]]&lt;br /&gt;
# [[CID_aplicatii_10 : Aplicatii cu numaratoare]]&lt;br /&gt;
# [[CID_aplicatii_11 : Automate finite]]&lt;br /&gt;
# [[CID_aplicatii_12 : Exercitii cu circuite secventiale]]&lt;br /&gt;
# CID_aplicatii_13 : Lucrarea 2 - circuite secventiale&lt;br /&gt;
# [[CID_aplicatii_14 : Circuite digitale complexe]]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_1_:_Generare_de_forme_de_unda&amp;diff=8271</id>
		<title>CID aplicatii 1 : Generare de forme de unda</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_1_:_Generare_de_forme_de_unda&amp;diff=8271"/>
		<updated>2026-02-25T08:33:30Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;În această sesiune de aplicații vom învăța cum să generăm semnale digitale cu ajutorul limbajului SystemVerilog. Generarea de semnale este utilizată în testarea prin simulare a circuitelor digitale. Semnalele generate sunt introduse la intrarea circuitului, observându-se apoi cum se modifică starea ieșirilor acestuia.&lt;br /&gt;
&lt;br /&gt;
Proiectarea circuitelor digitale se bazează pe generarea unor circuite digitale fizice. Deși se va scrie cod în limbajul SystemVerilog, mereu trebuie avut în vedere faptul că în spate se va genera un circuit fizic, codul nu se rulează pas cu pas, aceasta fiind deosebirea fundamentală dintre limbajele de descriere hardware (generează circuite fizice) și limbajele de programare (cod care se execută pas cu pas). Unele concepte cât și unele elemente de sintaxa este posibil să semene cu ce ați facut la programare, dar este important să  înțelegeți că prin codul scris se desenează/generează circuite. Sau invers, pornind de la un desen, se poate face o descriere în SystemVerilog a acestuia.&lt;br /&gt;
&lt;br /&gt;
Proiectele exemplu care pot fi descărcate au fost implementate folosind Vivado 2021.2. Dacă aveți altă versiune este posibil să vă ceară să le salvați în versiunea respectivă sau să fie nevoie să vă faceți un proiect nou, în care să adaugați fișierele cu cod.&lt;br /&gt;
&lt;br /&gt;
==Noțiuni și cunoștințe necesare==&lt;br /&gt;
 &lt;br /&gt;
* [[Introducere. SystemVerilog HDL]] (Sintaxa [[SystemVerilog]])&lt;br /&gt;
&lt;br /&gt;
* [[Tutorial Vivado]].&lt;br /&gt;
&lt;br /&gt;
==Modulul de test (Testbench)==&lt;br /&gt;
Modulul de test este un modul nesintetizabil (nu poate fi transformat într-un circuit de către utilitarul care realizează sinteza) și este folosit, așa cum sugerează și numele, în testarea circuitelor. Acest modul este folosit exclusiv în simulare. Simularea permite detecția rapidă a erorilor de implementare și corectarea acestora. Ideea generală a unui modul de test este descrisă în figura de mai jos (considerăm un circuit cu numele &amp;#039;&amp;#039;circuit&amp;#039;&amp;#039; și modulul său de test &amp;#039;&amp;#039;circuit_tb&amp;#039;&amp;#039;):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CircuitTestbench.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
După cum se vede în figura de mai sus, modulul de test conține printre altele și un &amp;#039;&amp;#039;&amp;#039;generator de semnale de test&amp;#039;&amp;#039;&amp;#039;. Acesta are rolul de a genera câte un semnal de test pentru fiecare intrare a circuitului. Forma acestor semnale de test este stabilită de către cel care realizează verificarea și trebuie aleasă astfel încât să detectăm cât mai multe posibile erori.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
====Exemplul 1: Generarea a doua semnale digitale de 1 bit====&lt;br /&gt;
Să se genereze două semnale digitale de 1 bit, care să aibă următoarea variație în timp (unitatea de timp este de 1ns):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CID Aplicatii1 ex1.svg|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     // setăm unitatea de timp la 1ns, cu o precizie de 1ps&lt;br /&gt;
&lt;br /&gt;
module waveform1();    // modulul se numește waveform1 și nu are nicio intrare și nicio ieșire. Semnalele de test generate sunt semnale interne.&lt;br /&gt;
&lt;br /&gt;
logic a, b;              // cele două semnale de test sunt trebuie declarate ca elemente de tip logic.&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    $monitor(&amp;quot;time = %2d, a = %b, b=%b&amp;quot;, $time, a, b);  // monitorizăm în consolă starea semnalelor a si b&lt;br /&gt;
       a = 0;          // semnalul a va avea valoarea 0 la momentul inițial de timp (la momentul t = 0)&lt;br /&gt;
       b = 0;          // semnalul b va avea valoarea 0 la momentul inițial de timp (la momentul t = 0)&lt;br /&gt;
    #1 a = 1;          // după 1ns de la momentul inițial, a se face 1&lt;br /&gt;
    #1 b = 1;          // după 2ns de la momentul inițial, b se face 1&lt;br /&gt;
    #1 a = 0;          // după 3ns de la momentul inițial, a se face 0&lt;br /&gt;
       b = 0;          // după 3ns de la momentul inițial, b se face 0&lt;br /&gt;
    #2 $stop();        // simularea este oprită&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule              // incheiem descrierea modulului de generare de semnale digitale&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Atunci când un semnal are dimensiunea de 1 bit, nu va apărea nimic intre tipul acestuia și nume. Atunci când semnalul are o dimensiune mai mare sau egală cu doi biți, dimensiunea va fi descrisă sub forma &amp;#039;&amp;#039;&amp;#039;[n-1:0]&amp;#039;&amp;#039;&amp;#039;, unde &amp;#039;&amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;#039; este numărul de biți. Conform acestei descrieri, bitul &amp;#039;&amp;#039;&amp;#039;n-1&amp;#039;&amp;#039;&amp;#039; este cel mai semnificativ.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
logic a;           //semnal cu dimeniunea de 1 bit&lt;br /&gt;
logic [7:0] data;  //semnal/magistrală/bus cu dimensiunea de 8 biți&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Exemplul 2: Generarea unui semnal periodic de 1 bit====&lt;br /&gt;
Să se genereze un semnal digital periodic de 1 bit, cu perioada egală cu 2ns:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Clock wave.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     // setăm unitatea de timp la 1ns, cu o precizie de 1ps&lt;br /&gt;
&lt;br /&gt;
module waveform2();    // modulul se numește waveform2 si nu are nicio intrare și nicio iesire&lt;br /&gt;
&lt;br /&gt;
logic clock;             // semnalul de test este declarat de tip logic&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock = 0;              // valoarea inițială a semnalului va fi 0 (la momentul t = 0)&lt;br /&gt;
    forever                 // forever indică faptul că ce urmează se va repeta într-o buclă continuă. &lt;br /&gt;
    begin&lt;br /&gt;
        #1 clock = ~clock;  // La trecea unui timp egal cu unitatea de timp definită, semnalul clock iși va nega valoarea                         &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
   // fiind o singura instructiune in bucla &amp;quot;forever&amp;quot;, se putea omite begin/end =&amp;gt; forever #1 clock = ~clock; &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    #20 $stop();       // La 20 de unități de timp (aici, 20 ns), simularea se va opri. &lt;br /&gt;
                       // Aici punem $stop într-un bloc separat, deoarece forever blochează blocul initial în care se află&lt;br /&gt;
                       // Toate blocurile initial încep la același moment de timp (t = 0) și au efect în paralel&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;
==Exerciții==&lt;br /&gt;
====Exercițiul 1====&lt;br /&gt;
Generați două semnale digitale &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; de 1 bit, astfel încât să se formeze cu ele toate cele 4 combinații posibile, după cum urmează:&lt;br /&gt;
&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 0ns&amp;#039;&amp;#039;&amp;#039;: a = 0, b = 0&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 1ns&amp;#039;&amp;#039;&amp;#039;: a = 0, b = 1&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 2ns&amp;#039;&amp;#039;&amp;#039;: a = 1, b = 0&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 3ns&amp;#039;&amp;#039;&amp;#039;: a = 1, b = 1&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 2====&lt;br /&gt;
Să se genereze un semnal digital de 8 biți aliniat la fronturile crescătoare ale unui semnal periodic (semnal de ceas), ce are perioada de 2ns:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Clock and data wave.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Frontul crescător al unui semnal este definit ca tranziția dintre nivelul de 0 logic și 1 logic.&lt;br /&gt;
* Spunem că un semnal este aliniat la fronturile crescătoare ale unui alt semnal dacă acesta își modifică valoarea imediat după apariția acelui front crescător. În figura de mai sus, se observă că &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; își schimbă valoarea imediat după fiecare front crescător al semnalului &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Indicații&amp;#039;&amp;#039;&amp;#039;: &lt;br /&gt;
&lt;br /&gt;
* Așteptarea unui front crescător al semnalului &amp;#039;&amp;#039;NumeSemnal&amp;#039;&amp;#039; se realizează cu &amp;#039;&amp;#039;&amp;#039;@(posedge &amp;#039;&amp;#039;NumeSemnal&amp;#039;&amp;#039;)&amp;#039;&amp;#039;&amp;#039;. Aceasta va înlocui întârzierile de tip &amp;#039;&amp;#039;&amp;#039;#n&amp;#039;&amp;#039;&amp;#039; folosite anterior.&lt;br /&gt;
* Pentru semnalele ce se doresc aliniate la un eveniment de tip &amp;#039;&amp;#039;&amp;#039;posedge&amp;#039;&amp;#039;&amp;#039;, vom folosi atribuirea non-blocantă: de exemplu, &amp;#039;&amp;#039;&amp;#039;data &amp;lt;= 1;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* Nu uitați! Folosirea &amp;#039;&amp;#039;forever&amp;#039;&amp;#039; pentru generarea semnalului de ceas va bloca acel bloc &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;.&lt;br /&gt;
* Incrementarea valorii unui semnal se poate realiza cu un bloc de tip &amp;#039;&amp;#039;for&amp;#039;&amp;#039;, inclus in blocul &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;. Blocul &amp;#039;&amp;#039;for&amp;#039;&amp;#039; va avea nevoie de un contor de tip &amp;#039;&amp;#039;integer&amp;#039;&amp;#039;, declarat în afara blocului &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;. Pentru mai multe detalii, consultați tutorialul de sintaxa SystemVerilog.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Folosind indicațiile anterioare, înlocuiți al doilea bloc &amp;#039;&amp;#039;initial&amp;#039;&amp;#039; din &amp;#039;&amp;#039;&amp;#039;Exemplul 2&amp;#039;&amp;#039;&amp;#039; cu următoarea secvență și completați liniile de cod lipsă:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
integer index;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    for(index = 0; index &amp;lt; 11; index = index + 1) begin&lt;br /&gt;
        //completati codul    &lt;br /&gt;
    end&lt;br /&gt;
    #20 $stop();&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 3====&lt;br /&gt;
Desenați formele de undă ale semnalelor de test &amp;#039;&amp;#039;a&amp;#039;&amp;#039;, &amp;#039;&amp;#039;b&amp;#039;&amp;#039; și &amp;#039;&amp;#039;c&amp;#039;&amp;#039;, generate cu ajutorul următoarelor două blocuri &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     &lt;br /&gt;
&lt;br /&gt;
module waveform();    &lt;br /&gt;
&lt;br /&gt;
logic a, b, c; &lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       a = 0;          &lt;br /&gt;
       b = 0;          &lt;br /&gt;
    #2 b = 1;          &lt;br /&gt;
    #1 a = 1;          &lt;br /&gt;
    #3 b = 0;          &lt;br /&gt;
    #3 a = 0;          &lt;br /&gt;
    #2 $stop();       &lt;br /&gt;
end   &lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       c = 1;                   &lt;br /&gt;
    #2 c = 0;          &lt;br /&gt;
    #3 c = 1;                &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;
====Exercițiul 4====&lt;br /&gt;
Generati un semnal digital &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039; cu dimensiunea de 1 bit si perioada de 2ns si un semnal digital &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039;, cu dimensiunea de 4 biti, aliniat la fronturile crescatoare ale semnalului &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039;. Semnalul &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; va varia astfel: &amp;#039;&amp;#039;&amp;#039;0, 1, 2, 3, 0, 1, 2 ,3, 0, 1 ... &amp;#039;&amp;#039;&amp;#039;. Opriti simularea dupa ce semnalul &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; a realizat 4 variatii complete (s-a generat secventa &amp;#039;&amp;#039;&amp;#039;0, 1, 2, 3&amp;#039;&amp;#039;&amp;#039; de 4 ori).&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_12_:_Exercitii_cu_circuite_secventiale&amp;diff=8126</id>
		<title>CID aplicatii 12 : Exercitii cu circuite secventiale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_12_:_Exercitii_cu_circuite_secventiale&amp;diff=8126"/>
		<updated>2025-06-05T07:50:05Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 2 in anii anteriori.&lt;br /&gt;
&lt;br /&gt;
Unele exercitii contin si automate. Daca acestea nu au fost inca predate, puteti ignora partea aceea de circuit.&lt;br /&gt;
&lt;br /&gt;
Dupa cum se poate observa, exemplele sunt diverse ca domeniu de aplicabilitate. Prin asta se doreste a se arata importanta si diversitatea circuitelor digitale in societatea moderna.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: password checker===&lt;br /&gt;
&lt;br /&gt;
SystemVerilog suporta codul ASCII deci puteti introduce si litere/string-uri care vor fi tratate prin reprezentarea lor binara.&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/5/5c/Subiect_l2_password_checker.pdf password_checker.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: PWM static pe RGB ===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/f/f2/Subiect_pwm_l2.pdf PWM_static_pe_RGB.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: calculator de siruri dupa formula data===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/a/a2/Subiect_l2_sir_calculator.pdf calculator_siruri.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: UART tx - structural===&lt;br /&gt;
&lt;br /&gt;
UART este un standard pentru transmisiune de date seriale. Pentru o descriere a protocolului puteti citi: [https://www.circuitbasics.com/basics-uart-communication/ functionare_uart]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/d/d0/Subiect_l2_uart_tx.pdf uart_tx.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: UART rx - behavioural=== &lt;br /&gt;
&lt;br /&gt;
Daca ati inteles cum functioneaza mecanismul de UART (si pentru a testa functionarea TX de la exercitiul anterior) puteti scrie modulul de RX (receiver) al protocolului, astfel incat cele 2 sa comunice intre ele.&lt;br /&gt;
&lt;br /&gt;
La nivel de TB ar fi amandoua instantiate si conectate intre ele. &lt;br /&gt;
&lt;br /&gt;
UART RX ar trebui sa scoata un puls al semnalului &amp;quot;valid&amp;quot; impreuna cu 8 biti de date daca transmisiunea a fost efectuata cu succes, datele care ies din el fiind cele care au intrat in modulul de tx. &lt;br /&gt;
&lt;br /&gt;
Pentru a compara abordarea structurala cu cea comportamentala, acest modul se doreste a fi facut comportamental.&lt;br /&gt;
In always-urile acestuia vor aparea mecanisme de numarare care practic alcatuiesc un mic FSM de control. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: microcontrollere - oscillator control register=== &lt;br /&gt;
&lt;br /&gt;
Acest subiect prezinta un modul simplificat al mecanismului de control al oscilatorului de pe un microcontroller. Acest modul controleaza generarea smenalului de ceas ce se propaga catre microcontroller si deci viteza la care sistemul va functiona.&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/0/09/Subiect_l2_uc_osccon.pdf uc_osccon.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 7: Led care se invarte===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/a/af/L2_led_care_se_invarte.pdf Led_care_se_invarte.pdf]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_12_:_Exercitii_cu_circuite_secventiale&amp;diff=8125</id>
		<title>CID aplicatii 12 : Exercitii cu circuite secventiale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_12_:_Exercitii_cu_circuite_secventiale&amp;diff=8125"/>
		<updated>2025-06-05T07:49:46Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 2 in anii anteriori.&lt;br /&gt;
&lt;br /&gt;
Unele exercitii contin si automate. Daca acestea nu au fost inca predate, puteti ignora partea aceea de circuit.&lt;br /&gt;
&lt;br /&gt;
Dupa cum se poate observa, exemplele sunt diverse ca domeniu de aplicabilitate. Prin asta se doreste a se arata importanta si diversitatea circuitelor digitale in societatea moderna.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: password checker===&lt;br /&gt;
&lt;br /&gt;
SystemVerilog suporta codul ASCII deci puteti introduce si litere/string-uri care vor fi tratate prin reprezentarea lor binara.&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/5/5c/Subiect_l2_password_checker.pdf password_checker.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: PWM static pe RGB ===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/f/f2/Subiect_pwm_l2.pdf PWM_static_pe_RGB.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: calculator de siruri dupa formula data===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/a/a2/Subiect_l2_sir_calculator.pdf calculator_siruri.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: UART tx - structural===&lt;br /&gt;
&lt;br /&gt;
UART este un standard pentru transmisiune de date seriale. Pentru o descriere a protocolului puteti citi: [https://www.circuitbasics.com/basics-uart-communication/ functionare_uart]&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/d/d0/Subiect_l2_uart_tx.pdf uart_tx.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: UART rx - behavioural=== &lt;br /&gt;
&lt;br /&gt;
Daca ati inteles cum functioneaza mecanismul de UART (si pentru a testa functionarea TX de la exercitiul anterior) puteti scrie modulul de RX (receiver) al protocolului, astfel incat cele 2 sa comunice intre ele.&lt;br /&gt;
&lt;br /&gt;
La nivel de TB ar fi amandoua instantiate si conectate intre ele. &lt;br /&gt;
&lt;br /&gt;
UART RX ar trebui sa scoata un puls al semnalului &amp;quot;valid&amp;quot; impreuna cu 8 biti de date daca transmisiunea a fost efectuata cu succes, datele care ies din el fiind cele care au intrat in modulul de tx. &lt;br /&gt;
&lt;br /&gt;
Pentru a compara abordarea structurala cu cea comportamentala, acest modul se doreste a fi facut comportamental.&lt;br /&gt;
In always-urile acestuia vor aparea mecanisme de numarare care practic alcatuiesc un mic FSM de control. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: microcontrollere - oscillator control register=== &lt;br /&gt;
&lt;br /&gt;
Acest subiect prezinta un modul simplificat al mecanismului de control al oscilatorului de pe un microcontroller. Acest modul controleaza generarea smenalului de ceas ce se propaga catre microcontroller si deci viteza la care sistemul va functiona.&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/0/09/Subiect_l2_uc_osccon.pdf uc_osccon.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 7: Led care se invarte===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/a/af/L2_led_care_se_invarte.pdf Led_care_se_invarte.pdf]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:L2_led_care_se_invarte.pdf&amp;diff=8124</id>
		<title>Fișier:L2 led care se invarte.pdf</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:L2_led_care_se_invarte.pdf&amp;diff=8124"/>
		<updated>2025-06-05T07:49:05Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Subiect.pdf&amp;diff=8123</id>
		<title>Fișier:Subiect.pdf</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Subiect.pdf&amp;diff=8123"/>
		<updated>2025-06-05T07:46:28Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Subiect_pwm_l2.pdf&amp;diff=8122</id>
		<title>Fișier:Subiect pwm l2.pdf</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Subiect_pwm_l2.pdf&amp;diff=8122"/>
		<updated>2025-06-05T07:42:57Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8121</id>
		<title>CID aplicatii 5 : Exercitii cu circuite combinationale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8121"/>
		<updated>2025-06-05T07:40:15Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exercitiul 6: Calcul si Flag-uri */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostiintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 1 in anii anteriori si cateva notiuni de teorie si sintaxa ajutatoare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: Parametrizare==&lt;br /&gt;
Parametrizarea este un mod de a generaliza codul scris pentru a nu fi nevoie sa scrii acelasi modul de mai multe ori doar pentru ca circuitul isi schimba o dimensiune. &lt;br /&gt;
&lt;br /&gt;
Pentru a intelege mai clar avantajele si sintaxa urmariti urmatorul exemplu:&lt;br /&gt;
&lt;br /&gt;
Fisierul sumator.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator # // &amp;lt;= diez deoarece urmeaza lista cu paramteri&lt;br /&gt;
				( // parametri &lt;br /&gt;
					parameter data_size = 4 // valoare default 4&lt;br /&gt;
					// alti parametri aici daca este nevoie, separati prin virgula&lt;br /&gt;
				)&lt;br /&gt;
				( // interfata &lt;br /&gt;
					input logic [data_size-1:0] in0, // si pot folosii parametrul &amp;quot;data_size&amp;quot; pentru dimensiunea bus-ului&lt;br /&gt;
					input logic [data_size-1:0] in1,&lt;br /&gt;
					output logic [data_size-1:0] out0&lt;br /&gt;
				);&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 + in1;				&lt;br /&gt;
				&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cand se instantiaza un modul parametrizat, se specifica valorile parametrilor astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(8)   // se genereaza un sumator pe 8b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_0&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out0)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(32)  // se genereaza un sumator pe 32b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_1&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator nume_instanta_2 // se genereaza un sumator de dimensiune default, aici 4, asa cum e scris in modulul &amp;quot;sumator&amp;quot;&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out2)&lt;br /&gt;
	);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puteti folosi parametrizarea in exercitiul 3 de mai jos. Acolo sunt 2 tipuri de multiplexoare, unul cu intrarile pe 1 bit si unul cu intrarile pe 2 biti. Poate fi scris un singur modul parametrizat care sa acopere ambele situatii.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Concatenarea==&lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara conectare a firelor sau pentru o mai buna organizare si expresivitate a codului, de multe ori este util ca fire individuale sa fie grupate impreuna sau ca un bus de mai multi biti sa fie separat in fire individuale. Acest lucru se face folosind concatenarea, prin simbolurile &amp;quot;{ }&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Un exemplu de folosire a concatenarii este oferit mai jos.&lt;br /&gt;
Un sumator pe 8b are rezultatul pe maxim 9b, in cazul in care ambele numere sunt mari. Astfel apare un bit de carry out. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator ( &lt;br /&gt;
            input logic [7:0] in0,&lt;br /&gt;
            input logic [7:0] in1,&lt;br /&gt;
            output logic [7:0] out0,&lt;br /&gt;
            output logic carry_out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign {carry_out,out0} = in0 + in1; // fac suma intre in0 si in1 iar rezultatul il pun pe cei 9b alcatuiti din: 1b carry_out si 8b out0, in ordinea asta&lt;br /&gt;
&lt;br /&gt;
endmodule       &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Se pot concatena oricat de multe semnale, puse in &amp;quot;{ }&amp;quot; si separate prin virgula. Atentie la dimensiunile firelor care se concateneaza.&lt;br /&gt;
&lt;br /&gt;
Se poate de asemenea face concatenare si la dreapta egalului, astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fir_pe_10_b = {fir_pe_3b,fir_pe_5b,fir_pe_1b,fir_pe_1b};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In exemplul anterior ultimi 2b ai &amp;quot;fir_pe_10_b&amp;quot; vor avea mereu aceeasi valoare, provenind din acelasi fir. Sintaxa SystemVerilog permite asta.&lt;br /&gt;
&lt;br /&gt;
Puteti folosii concatenarea, in exercitiul 2, la flag-ul de overflow.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Constante ca intrari in circuite==&lt;br /&gt;
In cazul in care se doreste scrierea unor constante la intrarea unor module, acestea se pun direct intre paranteze la instantiere. &lt;br /&gt;
De exemplu, pentru multiplexorul de jos din subiectul &amp;quot;alu structural&amp;quot;, intrarea &amp;quot;in3&amp;quot; este conectata la valoarea &amp;quot;1&amp;quot;. Sintaxa pentru aceasta este: &amp;quot;.in3(1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: &amp;quot;_&amp;quot;==&lt;br /&gt;
Simbolul &amp;quot;_&amp;quot; (underscore) este ignorat de SystemVerilog si ajuta vizual la citirea semnalelor pe mai multi biti. De exemplu 16&amp;#039;b1010010111110000 este identic cu 16&amp;#039;b1010_0101_1111_0000, al doilea fiind totusi mai usor de citit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 0: Repararea erorilor===&lt;br /&gt;
Arhiva de mai jos contine mai multe proiecte in Vivado, fiecare avand cate o eroare de sintaxa sau de logica. In vederea aprofundari cunostiintelor voastre (si pentru lucrarea de saptamana urmatoare), incercati sa le parcurgeti si sa rezolvati toate problemele. &lt;br /&gt;
Pe langa proiecte in sine, in arhiva se afla si un fisier text cu o introducere, rezolvarile si explicatiile pentru fiecare situatie.&lt;br /&gt;
&lt;br /&gt;
[https://drive.google.com/file/d/1cNTpQC54_JEeSk8SxgHTEdGtobCn_-EI/view?usp=drive_link Arhiva_proiecte_cu_erori.zip]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: ALU - descriere comportamentala===&lt;br /&gt;
Descrieți comportamental o unitate aritmetico-logică (ALU) care are la intrare 2 numere binare de câte 8 biți și poate calcula următoarele funcții:&lt;br /&gt;
:- suma celor două numere&lt;br /&gt;
:- diferența celor două numere&lt;br /&gt;
:- operații logice bit cu bit (bitwise): SI, SAU, XOR și inversele lor&lt;br /&gt;
:- operandul din stanga trece neschimbat&lt;br /&gt;
:- operandul din dreapta trece neschimbat&lt;br /&gt;
:- numărul din stânga este deplasat la stânga cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
:- numărul din stânga este deplasat la dreapta cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
&lt;br /&gt;
Funcția executată la un anumit moment este determinată de configurația binară de pe intrarea de comandă (function).&lt;br /&gt;
&lt;br /&gt;
ALU are de asemenea intrare de carry și ieșire de carry, plus alte două ieșiri - indicatori - pentru cazurile când rezultatul este zero și când cei doi operanzi sunt egali.&lt;br /&gt;
&lt;br /&gt;
Intrarea de control va fi facuta pe 4 biti ca sa permita existenta a 16 operatii posibile. Fiecare numar de pe intrarea de control (combinatie de 0 si 1) va reprezenta o operatie din cele de mai sus. Scrierea se va face folosind un bloc &amp;quot;case&amp;quot; in functie de aceasta intrare. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: ALU - descriere structurala===&lt;br /&gt;
 &lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/8f/Subiect_big_alu.pdf subiect_alu.pdf]&lt;br /&gt;
	&lt;br /&gt;
Daca se doreste selectarea doar a anumitor biti dintr-un bus (cum se vrea din instruction) acest lucru se poate face in 2 feluri:&lt;br /&gt;
&lt;br /&gt;
a) cu fir aditional:&lt;br /&gt;
:&amp;#039;&amp;#039;wire [1:0] fir_aditional1;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;assign fir_aditional1 = instruction[11:10];&amp;#039;&amp;#039;&lt;br /&gt;
:// apoi la instantiere: &amp;#039;&amp;#039;.sel(fir_aditional1),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
b) direct in instantiere;&lt;br /&gt;
:la instantierea celor 2 mux4 din stanga, direct: &lt;br /&gt;
::&amp;#039;&amp;#039;.sel(instruction[11:10]),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie mai putin (a nu face toate modulele de calcul separat + instantierea lor) si pentru ca e vorba de operatii simple, se poate pune operatia cu assign direct in top pe un fir declarat acolo, sau si mai prescurtat, direct operatia dorita cand se intantiaza modulul in care aceasta intra. De exemplu, pentru operatia de shift la dreapta care intra in primul multiplexor, se poate pune:  &amp;quot;.in0(data0 &amp;gt;&amp;gt; data1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Multiplexoare===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/3/3a/Subiect_muxes.pdf subiect_muxes.pdf]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Rom/Look-up table===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2e/Subiect_rom_luts.pdf rom_luts.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Sumator cu reprezentare in cifre zecimale===&lt;br /&gt;
Proiectati si verificati un sumator zecimal pentru numere cu 2 cifre&lt;br /&gt;
&lt;br /&gt;
Modulul de top (Figura 1) este alcatuit din 2 blocuri de tip &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;. Fiecare bloc aduna cifrele de pe aceasi pozitie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 1&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
   Top level&lt;br /&gt;
&lt;br /&gt;
[[Fișier: bcdsum.png]]&lt;br /&gt;
&lt;br /&gt;
Blocul &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; (Figura 2) este alcatuit din 4 blocuri, 2 sumatoare binare pe 4 biti (de tip &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039;), o instanta de &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039; si un multiplexor elementar mux2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 2&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
   Blocul DIGIT SUM &lt;br /&gt;
&lt;br /&gt;
[[Fișier: digit.png]]&lt;br /&gt;
&lt;br /&gt;
Primul sumator aduna cifrele din domeniul [0...9] avand un rezultat intre [0 ... 18] &lt;br /&gt;
&lt;br /&gt;
Comparatorul are la iesire 1 daca rezultatul este mai mare decat 9.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mic decat 9, acesta este trimis in mod direct la iesirea &amp;#039;&amp;#039;&amp;#039;digit&amp;#039;&amp;#039;&amp;#039; a blocului &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mare decat 9, o crectie este necesara si se aduna 6 la rezultat.&lt;br /&gt;
&lt;br /&gt;
Comparatorul cu valoarea 9 este descris structural din porti in figura de mai jos: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 3&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
   the comparator &lt;br /&gt;
&lt;br /&gt;
[[Fișier: cmp.png]]&lt;br /&gt;
&lt;br /&gt;
Testbench-ul va genera stimuli pentru &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
Intrarea b0 a &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; se schimba la fiecare 5 pasi de simulare .&lt;br /&gt;
&lt;br /&gt;
b1, a0 si a1 se schimba sincron cu b0 ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: teststimuli.png]]&lt;br /&gt;
&lt;br /&gt;
Cerinte:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039;- descris structural la nivel de porti ca in Figura 3.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039; descris comportamental cu un assign continuu.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;mux&amp;#039;&amp;#039;&amp;#039; descris comportamental cu always.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; descris strctural ca in Figura 2.&lt;br /&gt;
# modulul de top numit &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039;, descris structural ca in Figure 1.&lt;br /&gt;
# modulul de testbench, &amp;#039;&amp;#039;&amp;#039;bcdsum_tb&amp;#039;&amp;#039;&amp;#039;, instantiaza &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; cu numele &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# in testbench, generati stimuli pentru intrarile circuitului testat.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Codor Cezar===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/9/92/Cid_L1_codor_Cezar.pdf Codor_Cezar.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 7: Calcul si Flag-uri===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/c/c2/L1_calcul_si_flaguri.pdf Calcul_si_flaguri.pdf]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8120</id>
		<title>CID aplicatii 5 : Exercitii cu circuite combinationale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8120"/>
		<updated>2025-06-05T07:39:52Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostiintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 1 in anii anteriori si cateva notiuni de teorie si sintaxa ajutatoare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: Parametrizare==&lt;br /&gt;
Parametrizarea este un mod de a generaliza codul scris pentru a nu fi nevoie sa scrii acelasi modul de mai multe ori doar pentru ca circuitul isi schimba o dimensiune. &lt;br /&gt;
&lt;br /&gt;
Pentru a intelege mai clar avantajele si sintaxa urmariti urmatorul exemplu:&lt;br /&gt;
&lt;br /&gt;
Fisierul sumator.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator # // &amp;lt;= diez deoarece urmeaza lista cu paramteri&lt;br /&gt;
				( // parametri &lt;br /&gt;
					parameter data_size = 4 // valoare default 4&lt;br /&gt;
					// alti parametri aici daca este nevoie, separati prin virgula&lt;br /&gt;
				)&lt;br /&gt;
				( // interfata &lt;br /&gt;
					input logic [data_size-1:0] in0, // si pot folosii parametrul &amp;quot;data_size&amp;quot; pentru dimensiunea bus-ului&lt;br /&gt;
					input logic [data_size-1:0] in1,&lt;br /&gt;
					output logic [data_size-1:0] out0&lt;br /&gt;
				);&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 + in1;				&lt;br /&gt;
				&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cand se instantiaza un modul parametrizat, se specifica valorile parametrilor astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(8)   // se genereaza un sumator pe 8b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_0&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out0)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(32)  // se genereaza un sumator pe 32b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_1&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator nume_instanta_2 // se genereaza un sumator de dimensiune default, aici 4, asa cum e scris in modulul &amp;quot;sumator&amp;quot;&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out2)&lt;br /&gt;
	);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puteti folosi parametrizarea in exercitiul 3 de mai jos. Acolo sunt 2 tipuri de multiplexoare, unul cu intrarile pe 1 bit si unul cu intrarile pe 2 biti. Poate fi scris un singur modul parametrizat care sa acopere ambele situatii.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Concatenarea==&lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara conectare a firelor sau pentru o mai buna organizare si expresivitate a codului, de multe ori este util ca fire individuale sa fie grupate impreuna sau ca un bus de mai multi biti sa fie separat in fire individuale. Acest lucru se face folosind concatenarea, prin simbolurile &amp;quot;{ }&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Un exemplu de folosire a concatenarii este oferit mai jos.&lt;br /&gt;
Un sumator pe 8b are rezultatul pe maxim 9b, in cazul in care ambele numere sunt mari. Astfel apare un bit de carry out. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator ( &lt;br /&gt;
            input logic [7:0] in0,&lt;br /&gt;
            input logic [7:0] in1,&lt;br /&gt;
            output logic [7:0] out0,&lt;br /&gt;
            output logic carry_out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign {carry_out,out0} = in0 + in1; // fac suma intre in0 si in1 iar rezultatul il pun pe cei 9b alcatuiti din: 1b carry_out si 8b out0, in ordinea asta&lt;br /&gt;
&lt;br /&gt;
endmodule       &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Se pot concatena oricat de multe semnale, puse in &amp;quot;{ }&amp;quot; si separate prin virgula. Atentie la dimensiunile firelor care se concateneaza.&lt;br /&gt;
&lt;br /&gt;
Se poate de asemenea face concatenare si la dreapta egalului, astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fir_pe_10_b = {fir_pe_3b,fir_pe_5b,fir_pe_1b,fir_pe_1b};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In exemplul anterior ultimi 2b ai &amp;quot;fir_pe_10_b&amp;quot; vor avea mereu aceeasi valoare, provenind din acelasi fir. Sintaxa SystemVerilog permite asta.&lt;br /&gt;
&lt;br /&gt;
Puteti folosii concatenarea, in exercitiul 2, la flag-ul de overflow.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Constante ca intrari in circuite==&lt;br /&gt;
In cazul in care se doreste scrierea unor constante la intrarea unor module, acestea se pun direct intre paranteze la instantiere. &lt;br /&gt;
De exemplu, pentru multiplexorul de jos din subiectul &amp;quot;alu structural&amp;quot;, intrarea &amp;quot;in3&amp;quot; este conectata la valoarea &amp;quot;1&amp;quot;. Sintaxa pentru aceasta este: &amp;quot;.in3(1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: &amp;quot;_&amp;quot;==&lt;br /&gt;
Simbolul &amp;quot;_&amp;quot; (underscore) este ignorat de SystemVerilog si ajuta vizual la citirea semnalelor pe mai multi biti. De exemplu 16&amp;#039;b1010010111110000 este identic cu 16&amp;#039;b1010_0101_1111_0000, al doilea fiind totusi mai usor de citit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 0: Repararea erorilor===&lt;br /&gt;
Arhiva de mai jos contine mai multe proiecte in Vivado, fiecare avand cate o eroare de sintaxa sau de logica. In vederea aprofundari cunostiintelor voastre (si pentru lucrarea de saptamana urmatoare), incercati sa le parcurgeti si sa rezolvati toate problemele. &lt;br /&gt;
Pe langa proiecte in sine, in arhiva se afla si un fisier text cu o introducere, rezolvarile si explicatiile pentru fiecare situatie.&lt;br /&gt;
&lt;br /&gt;
[https://drive.google.com/file/d/1cNTpQC54_JEeSk8SxgHTEdGtobCn_-EI/view?usp=drive_link Arhiva_proiecte_cu_erori.zip]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: ALU - descriere comportamentala===&lt;br /&gt;
Descrieți comportamental o unitate aritmetico-logică (ALU) care are la intrare 2 numere binare de câte 8 biți și poate calcula următoarele funcții:&lt;br /&gt;
:- suma celor două numere&lt;br /&gt;
:- diferența celor două numere&lt;br /&gt;
:- operații logice bit cu bit (bitwise): SI, SAU, XOR și inversele lor&lt;br /&gt;
:- operandul din stanga trece neschimbat&lt;br /&gt;
:- operandul din dreapta trece neschimbat&lt;br /&gt;
:- numărul din stânga este deplasat la stânga cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
:- numărul din stânga este deplasat la dreapta cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
&lt;br /&gt;
Funcția executată la un anumit moment este determinată de configurația binară de pe intrarea de comandă (function).&lt;br /&gt;
&lt;br /&gt;
ALU are de asemenea intrare de carry și ieșire de carry, plus alte două ieșiri - indicatori - pentru cazurile când rezultatul este zero și când cei doi operanzi sunt egali.&lt;br /&gt;
&lt;br /&gt;
Intrarea de control va fi facuta pe 4 biti ca sa permita existenta a 16 operatii posibile. Fiecare numar de pe intrarea de control (combinatie de 0 si 1) va reprezenta o operatie din cele de mai sus. Scrierea se va face folosind un bloc &amp;quot;case&amp;quot; in functie de aceasta intrare. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: ALU - descriere structurala===&lt;br /&gt;
 &lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/8f/Subiect_big_alu.pdf subiect_alu.pdf]&lt;br /&gt;
	&lt;br /&gt;
Daca se doreste selectarea doar a anumitor biti dintr-un bus (cum se vrea din instruction) acest lucru se poate face in 2 feluri:&lt;br /&gt;
&lt;br /&gt;
a) cu fir aditional:&lt;br /&gt;
:&amp;#039;&amp;#039;wire [1:0] fir_aditional1;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;assign fir_aditional1 = instruction[11:10];&amp;#039;&amp;#039;&lt;br /&gt;
:// apoi la instantiere: &amp;#039;&amp;#039;.sel(fir_aditional1),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
b) direct in instantiere;&lt;br /&gt;
:la instantierea celor 2 mux4 din stanga, direct: &lt;br /&gt;
::&amp;#039;&amp;#039;.sel(instruction[11:10]),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie mai putin (a nu face toate modulele de calcul separat + instantierea lor) si pentru ca e vorba de operatii simple, se poate pune operatia cu assign direct in top pe un fir declarat acolo, sau si mai prescurtat, direct operatia dorita cand se intantiaza modulul in care aceasta intra. De exemplu, pentru operatia de shift la dreapta care intra in primul multiplexor, se poate pune:  &amp;quot;.in0(data0 &amp;gt;&amp;gt; data1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Multiplexoare===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/3/3a/Subiect_muxes.pdf subiect_muxes.pdf]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Rom/Look-up table===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2e/Subiect_rom_luts.pdf rom_luts.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Sumator cu reprezentare in cifre zecimale===&lt;br /&gt;
Proiectati si verificati un sumator zecimal pentru numere cu 2 cifre&lt;br /&gt;
&lt;br /&gt;
Modulul de top (Figura 1) este alcatuit din 2 blocuri de tip &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;. Fiecare bloc aduna cifrele de pe aceasi pozitie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 1&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
   Top level&lt;br /&gt;
&lt;br /&gt;
[[Fișier: bcdsum.png]]&lt;br /&gt;
&lt;br /&gt;
Blocul &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; (Figura 2) este alcatuit din 4 blocuri, 2 sumatoare binare pe 4 biti (de tip &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039;), o instanta de &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039; si un multiplexor elementar mux2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 2&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
   Blocul DIGIT SUM &lt;br /&gt;
&lt;br /&gt;
[[Fișier: digit.png]]&lt;br /&gt;
&lt;br /&gt;
Primul sumator aduna cifrele din domeniul [0...9] avand un rezultat intre [0 ... 18] &lt;br /&gt;
&lt;br /&gt;
Comparatorul are la iesire 1 daca rezultatul este mai mare decat 9.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mic decat 9, acesta este trimis in mod direct la iesirea &amp;#039;&amp;#039;&amp;#039;digit&amp;#039;&amp;#039;&amp;#039; a blocului &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mare decat 9, o crectie este necesara si se aduna 6 la rezultat.&lt;br /&gt;
&lt;br /&gt;
Comparatorul cu valoarea 9 este descris structural din porti in figura de mai jos: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 3&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
   the comparator &lt;br /&gt;
&lt;br /&gt;
[[Fișier: cmp.png]]&lt;br /&gt;
&lt;br /&gt;
Testbench-ul va genera stimuli pentru &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
Intrarea b0 a &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; se schimba la fiecare 5 pasi de simulare .&lt;br /&gt;
&lt;br /&gt;
b1, a0 si a1 se schimba sincron cu b0 ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: teststimuli.png]]&lt;br /&gt;
&lt;br /&gt;
Cerinte:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039;- descris structural la nivel de porti ca in Figura 3.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039; descris comportamental cu un assign continuu.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;mux&amp;#039;&amp;#039;&amp;#039; descris comportamental cu always.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; descris strctural ca in Figura 2.&lt;br /&gt;
# modulul de top numit &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039;, descris structural ca in Figure 1.&lt;br /&gt;
# modulul de testbench, &amp;#039;&amp;#039;&amp;#039;bcdsum_tb&amp;#039;&amp;#039;&amp;#039;, instantiaza &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; cu numele &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# in testbench, generati stimuli pentru intrarile circuitului testat.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Codor Cezar===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/9/92/Cid_L1_codor_Cezar.pdf Codor_Cezar.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Calcul si Flag-uri===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/c/c2/L1_calcul_si_flaguri.pdf Calcul_si_flaguri.pdf]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:L1_calcul_si_flaguri.pdf&amp;diff=8119</id>
		<title>Fișier:L1 calcul si flaguri.pdf</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:L1_calcul_si_flaguri.pdf&amp;diff=8119"/>
		<updated>2025-06-05T07:39:00Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8118</id>
		<title>CID aplicatii 5 : Exercitii cu circuite combinationale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8118"/>
		<updated>2025-06-05T07:20:16Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exercitiul 5: Sumator cu reprezentare in cifre zecimale */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostiintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 1 in anii anteriori si cateva notiuni de teorie si sintaxa ajutatoare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: Parametrizare==&lt;br /&gt;
Parametrizarea este un mod de a generaliza codul scris pentru a nu fi nevoie sa scrii acelasi modul de mai multe ori doar pentru ca circuitul isi schimba o dimensiune. &lt;br /&gt;
&lt;br /&gt;
Pentru a intelege mai clar avantajele si sintaxa urmariti urmatorul exemplu:&lt;br /&gt;
&lt;br /&gt;
Fisierul sumator.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator # // &amp;lt;= diez deoarece urmeaza lista cu paramteri&lt;br /&gt;
				( // parametri &lt;br /&gt;
					parameter data_size = 4 // valoare default 4&lt;br /&gt;
					// alti parametri aici daca este nevoie, separati prin virgula&lt;br /&gt;
				)&lt;br /&gt;
				( // interfata &lt;br /&gt;
					input logic [data_size-1:0] in0, // si pot folosii parametrul &amp;quot;data_size&amp;quot; pentru dimensiunea bus-ului&lt;br /&gt;
					input logic [data_size-1:0] in1,&lt;br /&gt;
					output logic [data_size-1:0] out0&lt;br /&gt;
				);&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 + in1;				&lt;br /&gt;
				&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cand se instantiaza un modul parametrizat, se specifica valorile parametrilor astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(8)   // se genereaza un sumator pe 8b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_0&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out0)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(32)  // se genereaza un sumator pe 32b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_1&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator nume_instanta_2 // se genereaza un sumator de dimensiune default, aici 4, asa cum e scris in modulul &amp;quot;sumator&amp;quot;&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out2)&lt;br /&gt;
	);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puteti folosi parametrizarea in exercitiul 3 de mai jos. Acolo sunt 2 tipuri de multiplexoare, unul cu intrarile pe 1 bit si unul cu intrarile pe 2 biti. Poate fi scris un singur modul parametrizat care sa acopere ambele situatii.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Concatenarea==&lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara conectare a firelor sau pentru o mai buna organizare si expresivitate a codului, de multe ori este util ca fire individuale sa fie grupate impreuna sau ca un bus de mai multi biti sa fie separat in fire individuale. Acest lucru se face folosind concatenarea, prin simbolurile &amp;quot;{ }&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Un exemplu de folosire a concatenarii este oferit mai jos.&lt;br /&gt;
Un sumator pe 8b are rezultatul pe maxim 9b, in cazul in care ambele numere sunt mari. Astfel apare un bit de carry out. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator ( &lt;br /&gt;
            input logic [7:0] in0,&lt;br /&gt;
            input logic [7:0] in1,&lt;br /&gt;
            output logic [7:0] out0,&lt;br /&gt;
            output logic carry_out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign {carry_out,out0} = in0 + in1; // fac suma intre in0 si in1 iar rezultatul il pun pe cei 9b alcatuiti din: 1b carry_out si 8b out0, in ordinea asta&lt;br /&gt;
&lt;br /&gt;
endmodule       &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Se pot concatena oricat de multe semnale, puse in &amp;quot;{ }&amp;quot; si separate prin virgula. Atentie la dimensiunile firelor care se concateneaza.&lt;br /&gt;
&lt;br /&gt;
Se poate de asemenea face concatenare si la dreapta egalului, astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fir_pe_10_b = {fir_pe_3b,fir_pe_5b,fir_pe_1b,fir_pe_1b};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In exemplul anterior ultimi 2b ai &amp;quot;fir_pe_10_b&amp;quot; vor avea mereu aceeasi valoare, provenind din acelasi fir. Sintaxa SystemVerilog permite asta.&lt;br /&gt;
&lt;br /&gt;
Puteti folosii concatenarea, in exercitiul 2, la flag-ul de overflow.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Constante ca intrari in circuite==&lt;br /&gt;
In cazul in care se doreste scrierea unor constante la intrarea unor module, acestea se pun direct intre paranteze la instantiere. &lt;br /&gt;
De exemplu, pentru multiplexorul de jos din subiectul &amp;quot;alu structural&amp;quot;, intrarea &amp;quot;in3&amp;quot; este conectata la valoarea &amp;quot;1&amp;quot;. Sintaxa pentru aceasta este: &amp;quot;.in3(1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: &amp;quot;_&amp;quot;==&lt;br /&gt;
Simbolul &amp;quot;_&amp;quot; (underscore) este ignorat de SystemVerilog si ajuta vizual la citirea semnalelor pe mai multi biti. De exemplu 16&amp;#039;b1010010111110000 este identic cu 16&amp;#039;b1010_0101_1111_0000, al doilea fiind totusi mai usor de citit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 0: Repararea erorilor===&lt;br /&gt;
Arhiva de mai jos contine mai multe proiecte in Vivado, fiecare avand cate o eroare de sintaxa sau de logica. In vederea aprofundari cunostiintelor voastre (si pentru lucrarea de saptamana urmatoare), incercati sa le parcurgeti si sa rezolvati toate problemele. &lt;br /&gt;
Pe langa proiecte in sine, in arhiva se afla si un fisier text cu o introducere, rezolvarile si explicatiile pentru fiecare situatie.&lt;br /&gt;
&lt;br /&gt;
[https://drive.google.com/file/d/1cNTpQC54_JEeSk8SxgHTEdGtobCn_-EI/view?usp=drive_link Arhiva_proiecte_cu_erori.zip]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: ALU - descriere comportamentala===&lt;br /&gt;
Descrieți comportamental o unitate aritmetico-logică (ALU) care are la intrare 2 numere binare de câte 8 biți și poate calcula următoarele funcții:&lt;br /&gt;
:- suma celor două numere&lt;br /&gt;
:- diferența celor două numere&lt;br /&gt;
:- operații logice bit cu bit (bitwise): SI, SAU, XOR și inversele lor&lt;br /&gt;
:- operandul din stanga trece neschimbat&lt;br /&gt;
:- operandul din dreapta trece neschimbat&lt;br /&gt;
:- numărul din stânga este deplasat la stânga cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
:- numărul din stânga este deplasat la dreapta cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
&lt;br /&gt;
Funcția executată la un anumit moment este determinată de configurația binară de pe intrarea de comandă (function).&lt;br /&gt;
&lt;br /&gt;
ALU are de asemenea intrare de carry și ieșire de carry, plus alte două ieșiri - indicatori - pentru cazurile când rezultatul este zero și când cei doi operanzi sunt egali.&lt;br /&gt;
&lt;br /&gt;
Intrarea de control va fi facuta pe 4 biti ca sa permita existenta a 16 operatii posibile. Fiecare numar de pe intrarea de control (combinatie de 0 si 1) va reprezenta o operatie din cele de mai sus. Scrierea se va face folosind un bloc &amp;quot;case&amp;quot; in functie de aceasta intrare. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: ALU - descriere structurala===&lt;br /&gt;
 &lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/8f/Subiect_big_alu.pdf subiect_alu.pdf]&lt;br /&gt;
	&lt;br /&gt;
Daca se doreste selectarea doar a anumitor biti dintr-un bus (cum se vrea din instruction) acest lucru se poate face in 2 feluri:&lt;br /&gt;
&lt;br /&gt;
a) cu fir aditional:&lt;br /&gt;
:&amp;#039;&amp;#039;wire [1:0] fir_aditional1;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;assign fir_aditional1 = instruction[11:10];&amp;#039;&amp;#039;&lt;br /&gt;
:// apoi la instantiere: &amp;#039;&amp;#039;.sel(fir_aditional1),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
b) direct in instantiere;&lt;br /&gt;
:la instantierea celor 2 mux4 din stanga, direct: &lt;br /&gt;
::&amp;#039;&amp;#039;.sel(instruction[11:10]),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie mai putin (a nu face toate modulele de calcul separat + instantierea lor) si pentru ca e vorba de operatii simple, se poate pune operatia cu assign direct in top pe un fir declarat acolo, sau si mai prescurtat, direct operatia dorita cand se intantiaza modulul in care aceasta intra. De exemplu, pentru operatia de shift la dreapta care intra in primul multiplexor, se poate pune:  &amp;quot;.in0(data0 &amp;gt;&amp;gt; data1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3:===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/3/3a/Subiect_muxes.pdf subiect_muxes.pdf]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4:===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2e/Subiect_rom_luts.pdf rom_luts.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Sumator cu reprezentare in cifre zecimale===&lt;br /&gt;
Proiectati si verificati un sumator zecimal pentru numere cu 2 cifre&lt;br /&gt;
&lt;br /&gt;
Modulul de top (Figura 1) este alcatuit din 2 blocuri de tip &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;. Fiecare bloc aduna cifrele de pe aceasi pozitie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 1&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
   Top level&lt;br /&gt;
&lt;br /&gt;
[[Fișier: bcdsum.png]]&lt;br /&gt;
&lt;br /&gt;
Blocul &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; (Figura 2) este alcatuit din 4 blocuri, 2 sumatoare binare pe 4 biti (de tip &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039;), o instanta de &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039; si un multiplexor elementar mux2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 2&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
   Blocul DIGIT SUM &lt;br /&gt;
&lt;br /&gt;
[[Fișier: digit.png]]&lt;br /&gt;
&lt;br /&gt;
Primul sumator aduna cifrele din domeniul [0...9] avand un rezultat intre [0 ... 18] &lt;br /&gt;
&lt;br /&gt;
Comparatorul are la iesire 1 daca rezultatul este mai mare decat 9.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mic decat 9, acesta este trimis in mod direct la iesirea &amp;#039;&amp;#039;&amp;#039;digit&amp;#039;&amp;#039;&amp;#039; a blocului &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mare decat 9, o crectie este necesara si se aduna 6 la rezultat.&lt;br /&gt;
&lt;br /&gt;
Comparatorul cu valoarea 9 este descris structural din porti in figura de mai jos: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 3&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
   the comparator &lt;br /&gt;
&lt;br /&gt;
[[Fișier: cmp.png]]&lt;br /&gt;
&lt;br /&gt;
Testbench-ul va genera stimuli pentru &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
Intrarea b0 a &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; se schimba la fiecare 5 pasi de simulare .&lt;br /&gt;
&lt;br /&gt;
b1, a0 si a1 se schimba sincron cu b0 ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: teststimuli.png]]&lt;br /&gt;
&lt;br /&gt;
Cerinte:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039;- descris structural la nivel de porti ca in Figura 3.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039; descris comportamental cu un assign continuu.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;mux&amp;#039;&amp;#039;&amp;#039; descris comportamental cu always.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; descris strctural ca in Figura 2.&lt;br /&gt;
# modulul de top numit &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039;, descris structural ca in Figure 1.&lt;br /&gt;
# modulul de testbench, &amp;#039;&amp;#039;&amp;#039;bcdsum_tb&amp;#039;&amp;#039;&amp;#039;, instantiaza &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; cu numele &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# in testbench, generati stimuli pentru intrarile circuitului testat.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6:===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/9/92/Cid_L1_codor_Cezar.pdf Codor_Cezar.pdf]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_11_:_Automate_finite&amp;diff=8092</id>
		<title>CID aplicatii 11 : Automate finite</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_11_:_Automate_finite&amp;diff=8092"/>
		<updated>2025-05-16T09:25:40Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exemplul 2: Automat ce detecteaza fronturile crescatoare ale unui semnal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Automate finite ==&lt;br /&gt;
&lt;br /&gt;
Automatul finit este folosit pentru a descrie sisteme ce tranziteaza un numar finit de stari. Acest tip de sistem este foarte util atunci cand starile nu sunt tranzitate intr-un mod simplu, evident sau repetitiv. &lt;br /&gt;
&lt;br /&gt;
Automatul finit, numit și FSM (Finite State Machine), este un model matematic de computație, definit de următoarele elemente:&lt;br /&gt;
* O mulțime finită de simboluri de intrare, numită alfabet de intrare;&lt;br /&gt;
* O mulțime finită și nevidă de simboluri de ieșire, numită alfabet de ieșire;&lt;br /&gt;
* O mulțime finită și nevidă de stări, din care doar una, numită starea curentă, este activă la un moment dat;&lt;br /&gt;
* O stare inițială, care face parte din mulțimea stărilor;&lt;br /&gt;
* O funcție de tranziție a stărilor, care calculează starea următoare a automatului în funcție de starea curentă și de simbolul de intrare;&lt;br /&gt;
* O funcție de calcul a ieșirii, care determină simbolul de ieșire în funcție de starea curentă (în cazul automatelor de tip Moore) sau în funcție de starea curentă și de simbolul de intrare (în cazul automatelor de tip Mealy).&lt;br /&gt;
&lt;br /&gt;
[[[[Fișier:Fsm.png]]]]&lt;br /&gt;
&lt;br /&gt;
La fiecare front al ceasului, valoarea stării următoare, calculată de către CLC, va fi încărcată în registru. Dacă registrul are n biți, numărul maxim de stări care pot fi reprezentate este 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt;. Acest număr poate fi mai mic, în funcție de schema de codare a stărilor. De exemplu, pentru n = 4, folosind codarea binară se pot reprezenta cel mult 16 stări (0000, 0001, 0010, ..., 1111), în timp ce pentru codarea one-hot, în care doar un singur bit poate lua valoarea 1, se pot reprezenta 4 stări (1000, 0100, 0010, 0001).&lt;br /&gt;
&lt;br /&gt;
Pentru a reprezenta comportamentul unui automat finit, putem folosi grafuri sau organigrame, conventiile de notare depinzand de tipul automatului (Moore sau Mealy).&lt;br /&gt;
&lt;br /&gt;
== Exemple == &lt;br /&gt;
=== Exemplul 1: Automat ce detecteaza secvente de tipul 11....100....0===&lt;br /&gt;
In acest exemplu va fi implementat un automat care detecteaza secventele de tipul 11....100....0. Pentru aceasta, automatul va avea o intrare pe un bit (&amp;#039;&amp;#039;in&amp;#039;&amp;#039;, pe care va veni secventa de biti) si doua iesiri: &amp;#039;&amp;#039;detectOk&amp;#039;&amp;#039;, care semnalizeaza prin 1 ca nu a fost inca detectata o secventa ilegala si &amp;#039;&amp;#039;detectFail&amp;#039;&amp;#039;, care semnalizeaza prin 1 ca a fost detectata o secventa ilegala (un 1 dupa 0). &lt;br /&gt;
&lt;br /&gt;
Automatul va avea 3 stari: &lt;br /&gt;
* Q0 - STATE_READ1: automatul intra in aceasta stare la reset si va ramane in aceasta atata timp cat intrarea este 1 (inca nu a aparut niciun 0).&lt;br /&gt;
* Q1 - STATE_READ0: automatul intra in aceasta stare atunci cand apare pe intrare primul 0 si va ramane in aceasta atata timp cat pe intrare este 0.&lt;br /&gt;
* Q2 - STATE_ERROR: automatul intra in aceasta stare atunci cand apare un 1 dupa 0 si va ramane blocat aici pana la reset.&lt;br /&gt;
&lt;br /&gt;
Pentru a coda cele 3 stari avem nevoie de minim 2 biti: STATE_READ1 = 2&amp;#039;b00, STATE_READ0 = 2&amp;#039;b01, STATE_ERROR = 2&amp;#039;b10.&lt;br /&gt;
&lt;br /&gt;
Graful automatului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Organigrama FSM 111000.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea automatului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM1(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic detectOk,&lt;br /&gt;
    output logic detectFail&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
//Se asociaza sirurilor de biti folositi pentru codarea starilor nume ce pot fi folosite mai usor in cod.&lt;br /&gt;
//La compilare, numele vor fi inlocuite in cod cu numerele asociate la inceput.&lt;br /&gt;
localparam STATE_READ1 = 2&amp;#039;b00;&lt;br /&gt;
localparam STATE_READ0 = 2&amp;#039;b01;&lt;br /&gt;
localparam STATE_ERROR = 2&amp;#039;b10;&lt;br /&gt;
&lt;br /&gt;
logic [1:0] state, state_next;&lt;br /&gt;
&lt;br /&gt;
//registrul de stare&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= STATE_READ1;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
//circuit combinational pentru calculul starii urmatoare&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        STATE_READ1: begin&lt;br /&gt;
                         if(in == 0) state_next = STATE_READ0;&lt;br /&gt;
                     end&lt;br /&gt;
        STATE_READ0: begin&lt;br /&gt;
                         if(in == 1) state_next = STATE_ERROR;&lt;br /&gt;
                     end&lt;br /&gt;
        STATE_ERROR: state_next = STATE_ERROR;&lt;br /&gt;
        default: state_next = STATE_READ1;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//circuit combinational pentru calculul iesirilor&lt;br /&gt;
assign detectOk   = (state == STATE_READ0) || (state == STATE_READ1);&lt;br /&gt;
assign detectFail = (state == STATE_ERROR);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru FSM1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM1_TB();&lt;br /&gt;
&lt;br /&gt;
logic  clock_t;&lt;br /&gt;
logic  reset_t;&lt;br /&gt;
logic  in_t;&lt;br /&gt;
logic detectOk_t;&lt;br /&gt;
logic detectFail_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
        in_t &amp;lt;= 1;&lt;br /&gt;
        reset_t &amp;lt;= 1;&lt;br /&gt;
    #2  reset_t &amp;lt;= 0;&lt;br /&gt;
    #10 in_t &amp;lt;= 0;&lt;br /&gt;
    #10 in_t &amp;lt;= 1;&lt;br /&gt;
    #10 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
FSM1 DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset(reset_t),&lt;br /&gt;
    .in(in_t),&lt;br /&gt;
    .detectOk(detectOk_t),&lt;br /&gt;
    .detectFail(detectFail_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Automat ce detecteaza fronturile crescatoare ale unui semnal===&lt;br /&gt;
Automatul ce detecteaza fronturile crescatoare are un singur semnal de intrare &amp;#039;&amp;#039;in&amp;#039;&amp;#039;, care reprezinta semnalul analizat si o singura iesire, &amp;#039;&amp;#039;out&amp;#039;&amp;#039;, generand pe aceasta un puls lung cat o perioada de ceas la fiecare aparitie a unui front crescator pe &amp;#039;&amp;#039;in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Vom avea nevoie de 3 stari:&lt;br /&gt;
* Q0: automatul intra in aceasta stare la reset si va ramane in aceasta atata timp cat intrarea este 0 (inca nu a aparut niciun front crescator).&lt;br /&gt;
* Q1: automatul intra in aceasta stare atunci cand apare pe intrare un front crescator. Dupa aparitia frontului crescator sunt doua posibilitati: linia ramane in 1, ceea ce duce la trecerea in starea Q2 care va duce iesirea in 0 dupa o perioada de ceas, sau linia trece in 0 dupa un ciclu de ceas, ceea ce duce la revenirea in starea Q0.&lt;br /&gt;
* Q2: automatul intra in aceasta stare atunci cand linia de intrare ramane in 1 mai mult de o perioada de ceas. Automatul va ramane in aceasta stare atata timp cat &amp;#039;&amp;#039;in&amp;#039;&amp;#039; ramane in 1 si va reveni in starea Q0 imediat ce &amp;#039;&amp;#039;in&amp;#039;&amp;#039; revine in 0.&lt;br /&gt;
&lt;br /&gt;
Graful automatului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Organigrama FSM rising edge.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea automatului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_Moore(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
localparam Q0 = 2&amp;#039;b00;&lt;br /&gt;
localparam Q1 = 2&amp;#039;b01;&lt;br /&gt;
localparam Q2 = 2&amp;#039;b10;&lt;br /&gt;
&lt;br /&gt;
logic [1:0] state, state_next;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= Q0;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        Q0: begin&lt;br /&gt;
                if(in == 1) state_next = Q1;&lt;br /&gt;
            end&lt;br /&gt;
        Q1: begin&lt;br /&gt;
                if(in == 0) state_next = Q0;&lt;br /&gt;
                if(in == 1) state_next = Q2;&lt;br /&gt;
            end&lt;br /&gt;
        Q2: begin&lt;br /&gt;
                if(in == 0) state_next = Q0;&lt;br /&gt;
            end&lt;br /&gt;
        default: state_next = Q0;&lt;br /&gt;
	endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
assign out   = (state == Q1); // iesirea depinde numai de stare =&amp;gt; Moore&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_mealy(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
localparam stare_wait_1 = 1&amp;#039;b0;&lt;br /&gt;
localparam stare_wait_0 = 1&amp;#039;b1;&lt;br /&gt;
&lt;br /&gt;
logic state, state_next;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= stare_wait_1;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        stare_wait_1: begin&lt;br /&gt;
                if(in == 1) state_next = stare_wait_0;&lt;br /&gt;
            end&lt;br /&gt;
        stare_wait_0: begin&lt;br /&gt;
                if(in == 0) state_next = stare_wait_1;&lt;br /&gt;
            end&lt;br /&gt;
        default: state_next = stare_wait_1 ;&lt;br /&gt;
	endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
	// daca pana acum semnalul a fost &amp;quot;0&amp;quot; si astept sa vina &amp;quot;1&amp;quot; si intrarea chiar vine &amp;quot;1&amp;quot; =&amp;gt; am avut front crescator&lt;br /&gt;
assign out = (state==stare_wait_1) &amp;amp; (in==1); // in apare aici =&amp;gt; dependenta iesiri de intrare =&amp;gt; Mealy&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru FSM2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_TB();&lt;br /&gt;
&lt;br /&gt;
logic  clock_t;&lt;br /&gt;
logic  reset_t;&lt;br /&gt;
logic  in_t;&lt;br /&gt;
logic out_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
        in_t &amp;lt;= 0;&lt;br /&gt;
        reset_t &amp;lt;= 1;&lt;br /&gt;
    #2  reset_t &amp;lt;= 0;&lt;br /&gt;
    #10 in_t &amp;lt;= 1;&lt;br /&gt;
    #5	in_t &amp;lt;= 0;&lt;br /&gt;
    #10 in_t &amp;lt;= 1;&lt;br /&gt;
    #5	in_t &amp;lt;= 0;&lt;br /&gt;
    #10 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
FSM2_Moore DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset(reset_t),&lt;br /&gt;
    .in(in_t),&lt;br /&gt;
    .out(out_t)&lt;br /&gt;
);&lt;br /&gt;
   &lt;br /&gt;
endmodule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se poate observa ca automatele de tip Moore au un numar mai mare de stari iar automatele de tip Mealy au o logica mai complexa pentru calcularea iesirilor.&lt;br /&gt;
&lt;br /&gt;
==Exerciții==&lt;br /&gt;
=== Exercițiul 1 ===&lt;br /&gt;
Implementați un automat finit ce detectează fronturile descrescătoare. Acesta are un singur semnal de intrare &amp;#039;&amp;#039;in&amp;#039;&amp;#039;, care reprezintă semnalul analizat și o singură ieșire &amp;#039;&amp;#039;out&amp;#039;&amp;#039;, generând pe această un puls lung cât o perioadă de ceas la fiecare apariție a unui front descrescător pe &amp;#039;&amp;#039;in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Realizați implementarea SystemVerilog plecând de la graful automatului:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Graf FSM falling edge.png]]&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 2 ===&lt;br /&gt;
Implementați un automat finit ce detectează atât fronturile crescătoare, cât și pe cele descrescătoare.&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 3 ===&lt;br /&gt;
Să se implementeze un circuit care generează un semnal PWM cu un factor de umplere ce variază triungular, la fiecare front descrescător al unui semnal de intrare.&lt;br /&gt;
&lt;br /&gt;
Schema circuitului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:FSM Exercitiu.png]]&lt;br /&gt;
&lt;br /&gt;
Modulele componente ale circuitului sunt:&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FallingEdgeDetector&amp;#039;&amp;#039;&amp;#039;: Automat ce detectează fronturile descrescătoare ale semnalului de intrare.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TriangularCounter&amp;#039;&amp;#039;&amp;#039;: Automat ce generează la iesire secvența de numere 64, 128, 192, 255, 192, 128, 64.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Counter&amp;#039;&amp;#039;&amp;#039;: Numărător pe 8 biți cu reset sincron.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;COMP&amp;#039;&amp;#039;&amp;#039;: Comparator cu două intrări pe 8 biți. Ieșirea sa va fi 1 atunci când counter &amp;lt; out și 0 în rest.&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 4 ===&lt;br /&gt;
Implementați automatul de control al unui aparat care vinde ciocolata.&lt;br /&gt;
&lt;br /&gt;
O cafea costa 2.5 lei. Automatul accepta monezi de 50 de bani si hartii de 1 leu. Daca se depaseste suma, restul ramane in aparat si va fi folosit la urmatoarea tranzactie. Se accepta introducerea si a unei monezi si a unei bancnote in acelasi timp.&lt;br /&gt;
&lt;br /&gt;
Intrarile sistemului sunt: clock (1b), reset (1b), in_50_b (1b), in_100_b (1b); iesirile sistemului sunt: give_cioco(1b).&lt;br /&gt;
&lt;br /&gt;
Implementati automatul de control care va tine minte suma curenta si va da sau nu ciocolata in functie de aceasta. Implementati acest automat in ambele variante: Mealy si Moore.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_11_:_Automate_finite&amp;diff=8091</id>
		<title>CID aplicatii 11 : Automate finite</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_11_:_Automate_finite&amp;diff=8091"/>
		<updated>2025-05-16T09:25:14Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exemplul 1: Automat ce detecteaza secvente de tipul 11....100....0 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Automate finite ==&lt;br /&gt;
&lt;br /&gt;
Automatul finit este folosit pentru a descrie sisteme ce tranziteaza un numar finit de stari. Acest tip de sistem este foarte util atunci cand starile nu sunt tranzitate intr-un mod simplu, evident sau repetitiv. &lt;br /&gt;
&lt;br /&gt;
Automatul finit, numit și FSM (Finite State Machine), este un model matematic de computație, definit de următoarele elemente:&lt;br /&gt;
* O mulțime finită de simboluri de intrare, numită alfabet de intrare;&lt;br /&gt;
* O mulțime finită și nevidă de simboluri de ieșire, numită alfabet de ieșire;&lt;br /&gt;
* O mulțime finită și nevidă de stări, din care doar una, numită starea curentă, este activă la un moment dat;&lt;br /&gt;
* O stare inițială, care face parte din mulțimea stărilor;&lt;br /&gt;
* O funcție de tranziție a stărilor, care calculează starea următoare a automatului în funcție de starea curentă și de simbolul de intrare;&lt;br /&gt;
* O funcție de calcul a ieșirii, care determină simbolul de ieșire în funcție de starea curentă (în cazul automatelor de tip Moore) sau în funcție de starea curentă și de simbolul de intrare (în cazul automatelor de tip Mealy).&lt;br /&gt;
&lt;br /&gt;
[[[[Fișier:Fsm.png]]]]&lt;br /&gt;
&lt;br /&gt;
La fiecare front al ceasului, valoarea stării următoare, calculată de către CLC, va fi încărcată în registru. Dacă registrul are n biți, numărul maxim de stări care pot fi reprezentate este 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt;. Acest număr poate fi mai mic, în funcție de schema de codare a stărilor. De exemplu, pentru n = 4, folosind codarea binară se pot reprezenta cel mult 16 stări (0000, 0001, 0010, ..., 1111), în timp ce pentru codarea one-hot, în care doar un singur bit poate lua valoarea 1, se pot reprezenta 4 stări (1000, 0100, 0010, 0001).&lt;br /&gt;
&lt;br /&gt;
Pentru a reprezenta comportamentul unui automat finit, putem folosi grafuri sau organigrame, conventiile de notare depinzand de tipul automatului (Moore sau Mealy).&lt;br /&gt;
&lt;br /&gt;
== Exemple == &lt;br /&gt;
=== Exemplul 1: Automat ce detecteaza secvente de tipul 11....100....0===&lt;br /&gt;
In acest exemplu va fi implementat un automat care detecteaza secventele de tipul 11....100....0. Pentru aceasta, automatul va avea o intrare pe un bit (&amp;#039;&amp;#039;in&amp;#039;&amp;#039;, pe care va veni secventa de biti) si doua iesiri: &amp;#039;&amp;#039;detectOk&amp;#039;&amp;#039;, care semnalizeaza prin 1 ca nu a fost inca detectata o secventa ilegala si &amp;#039;&amp;#039;detectFail&amp;#039;&amp;#039;, care semnalizeaza prin 1 ca a fost detectata o secventa ilegala (un 1 dupa 0). &lt;br /&gt;
&lt;br /&gt;
Automatul va avea 3 stari: &lt;br /&gt;
* Q0 - STATE_READ1: automatul intra in aceasta stare la reset si va ramane in aceasta atata timp cat intrarea este 1 (inca nu a aparut niciun 0).&lt;br /&gt;
* Q1 - STATE_READ0: automatul intra in aceasta stare atunci cand apare pe intrare primul 0 si va ramane in aceasta atata timp cat pe intrare este 0.&lt;br /&gt;
* Q2 - STATE_ERROR: automatul intra in aceasta stare atunci cand apare un 1 dupa 0 si va ramane blocat aici pana la reset.&lt;br /&gt;
&lt;br /&gt;
Pentru a coda cele 3 stari avem nevoie de minim 2 biti: STATE_READ1 = 2&amp;#039;b00, STATE_READ0 = 2&amp;#039;b01, STATE_ERROR = 2&amp;#039;b10.&lt;br /&gt;
&lt;br /&gt;
Graful automatului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Organigrama FSM 111000.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea automatului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM1(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic detectOk,&lt;br /&gt;
    output logic detectFail&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
//Se asociaza sirurilor de biti folositi pentru codarea starilor nume ce pot fi folosite mai usor in cod.&lt;br /&gt;
//La compilare, numele vor fi inlocuite in cod cu numerele asociate la inceput.&lt;br /&gt;
localparam STATE_READ1 = 2&amp;#039;b00;&lt;br /&gt;
localparam STATE_READ0 = 2&amp;#039;b01;&lt;br /&gt;
localparam STATE_ERROR = 2&amp;#039;b10;&lt;br /&gt;
&lt;br /&gt;
logic [1:0] state, state_next;&lt;br /&gt;
&lt;br /&gt;
//registrul de stare&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= STATE_READ1;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
//circuit combinational pentru calculul starii urmatoare&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        STATE_READ1: begin&lt;br /&gt;
                         if(in == 0) state_next = STATE_READ0;&lt;br /&gt;
                     end&lt;br /&gt;
        STATE_READ0: begin&lt;br /&gt;
                         if(in == 1) state_next = STATE_ERROR;&lt;br /&gt;
                     end&lt;br /&gt;
        STATE_ERROR: state_next = STATE_ERROR;&lt;br /&gt;
        default: state_next = STATE_READ1;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//circuit combinational pentru calculul iesirilor&lt;br /&gt;
assign detectOk   = (state == STATE_READ0) || (state == STATE_READ1);&lt;br /&gt;
assign detectFail = (state == STATE_ERROR);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru FSM1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM1_TB();&lt;br /&gt;
&lt;br /&gt;
logic  clock_t;&lt;br /&gt;
logic  reset_t;&lt;br /&gt;
logic  in_t;&lt;br /&gt;
logic detectOk_t;&lt;br /&gt;
logic detectFail_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
        in_t &amp;lt;= 1;&lt;br /&gt;
        reset_t &amp;lt;= 1;&lt;br /&gt;
    #2  reset_t &amp;lt;= 0;&lt;br /&gt;
    #10 in_t &amp;lt;= 0;&lt;br /&gt;
    #10 in_t &amp;lt;= 1;&lt;br /&gt;
    #10 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
FSM1 DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset(reset_t),&lt;br /&gt;
    .in(in_t),&lt;br /&gt;
    .detectOk(detectOk_t),&lt;br /&gt;
    .detectFail(detectFail_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Automat ce detecteaza fronturile crescatoare ale unui semnal===&lt;br /&gt;
Automatul ce detecteaza fronturile crescatoare are un singur semnal de intrare &amp;#039;&amp;#039;in&amp;#039;&amp;#039;, care reprezinta semnalul analizat si o singura iesire, &amp;#039;&amp;#039;out&amp;#039;&amp;#039;, generand pe aceasta un puls lung cat o perioada de ceas la fiecare aparitie a unui front crescator pe &amp;#039;&amp;#039;in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Vom avea nevoie de 3 stari:&lt;br /&gt;
* Q0: automatul intra in aceasta stare la reset si va ramane in aceasta atata timp cat intrarea este 0 (inca nu a aparut niciun front crescator).&lt;br /&gt;
* Q1: automatul intra in aceasta stare atunci cand apare pe intrare un front crescator. Dupa aparitia frontului crescator sunt doua posibilitati: linia ramane in 1, ceea ce duce la trecerea in starea Q2 care va duce iesirea in 0 dupa o perioada de ceas, sau linia trece in 0 dupa un ciclu de ceas, ceea ce duce la revenirea in starea Q0.&lt;br /&gt;
* Q2: automatul intra in aceasta stare atunci cand linia de intrare ramane in 1 mai mult de o perioada de ceas. Automatul va ramane in aceasta stare atata timp cat &amp;#039;&amp;#039;in&amp;#039;&amp;#039; ramane in 1 si va reveni in starea Q0 imediat ce &amp;#039;&amp;#039;in&amp;#039;&amp;#039; revine in 0.&lt;br /&gt;
&lt;br /&gt;
Graful automatului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Organigrama FSM rising edge.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea automatului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_Moore(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
localparam Q0 = 2&amp;#039;b00;&lt;br /&gt;
localparam Q1 = 2&amp;#039;b01;&lt;br /&gt;
localparam Q2 = 2&amp;#039;b10;&lt;br /&gt;
&lt;br /&gt;
logic [1:0] state, state_next;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= Q0;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        Q0: begin&lt;br /&gt;
                if(in == 1) state_next = Q1;&lt;br /&gt;
            end&lt;br /&gt;
        Q1: begin&lt;br /&gt;
                if(in == 0) state_next = Q0;&lt;br /&gt;
                if(in == 1) state_next = Q2;&lt;br /&gt;
            end&lt;br /&gt;
        Q2: begin&lt;br /&gt;
                if(in == 0) state_next = Q0;&lt;br /&gt;
            end&lt;br /&gt;
        default: state_next = Q0;&lt;br /&gt;
	endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
assign out   = (state == Q1); // iesirea depinde numai de stare =&amp;gt; Moore&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_mealy(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
localparam stare_wait_1 = 1&amp;#039;b0;&lt;br /&gt;
localparam stare_wait_0 = 1&amp;#039;b1;&lt;br /&gt;
&lt;br /&gt;
logic state, state_next;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= stare_wait_1;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        stare_wait_1: begin&lt;br /&gt;
                if(in == 1) state_next = stare_wait_0;&lt;br /&gt;
            end&lt;br /&gt;
        stare_wait_0: begin&lt;br /&gt;
                if(in == 0) state_next = stare_wait_1;&lt;br /&gt;
            end&lt;br /&gt;
        default: state_next = stare_wait_1 ;&lt;br /&gt;
	endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
	// daca pana acum semnalul a fost &amp;quot;0&amp;quot; si astept sa vina &amp;quot;1&amp;quot; si intrarea chiar vine &amp;quot;1&amp;quot; =&amp;gt; am avut front crescator&lt;br /&gt;
assign out = (state==stare_wait_1) &amp;amp; (in==1); // in apare aici =&amp;gt; dependenta iesiri de intrare =&amp;gt; Mealy&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru FSM2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_TB();&lt;br /&gt;
&lt;br /&gt;
logic  clock_t;&lt;br /&gt;
logic  reset_t;&lt;br /&gt;
logic  in_t;&lt;br /&gt;
logic out_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
        in_t = 0;&lt;br /&gt;
        reset_t = 1;&lt;br /&gt;
    #2  reset_t = 0;&lt;br /&gt;
    #10 in_t = 1;&lt;br /&gt;
    #5	in_t = 0;&lt;br /&gt;
    #10 in_t = 1;&lt;br /&gt;
    #5	in_t = 0;&lt;br /&gt;
    #10 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
FSM2_Moore DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset(reset_t),&lt;br /&gt;
    .in(in_t),&lt;br /&gt;
    .out(out_t)&lt;br /&gt;
);&lt;br /&gt;
   &lt;br /&gt;
endmodule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se poate observa ca automatele de tip Moore au un numar mai mare de stari iar automatele de tip Mealy au o logica mai complexa pentru calcularea iesirilor.&lt;br /&gt;
&lt;br /&gt;
==Exerciții==&lt;br /&gt;
=== Exercițiul 1 ===&lt;br /&gt;
Implementați un automat finit ce detectează fronturile descrescătoare. Acesta are un singur semnal de intrare &amp;#039;&amp;#039;in&amp;#039;&amp;#039;, care reprezintă semnalul analizat și o singură ieșire &amp;#039;&amp;#039;out&amp;#039;&amp;#039;, generând pe această un puls lung cât o perioadă de ceas la fiecare apariție a unui front descrescător pe &amp;#039;&amp;#039;in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Realizați implementarea SystemVerilog plecând de la graful automatului:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Graf FSM falling edge.png]]&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 2 ===&lt;br /&gt;
Implementați un automat finit ce detectează atât fronturile crescătoare, cât și pe cele descrescătoare.&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 3 ===&lt;br /&gt;
Să se implementeze un circuit care generează un semnal PWM cu un factor de umplere ce variază triungular, la fiecare front descrescător al unui semnal de intrare.&lt;br /&gt;
&lt;br /&gt;
Schema circuitului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:FSM Exercitiu.png]]&lt;br /&gt;
&lt;br /&gt;
Modulele componente ale circuitului sunt:&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FallingEdgeDetector&amp;#039;&amp;#039;&amp;#039;: Automat ce detectează fronturile descrescătoare ale semnalului de intrare.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TriangularCounter&amp;#039;&amp;#039;&amp;#039;: Automat ce generează la iesire secvența de numere 64, 128, 192, 255, 192, 128, 64.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Counter&amp;#039;&amp;#039;&amp;#039;: Numărător pe 8 biți cu reset sincron.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;COMP&amp;#039;&amp;#039;&amp;#039;: Comparator cu două intrări pe 8 biți. Ieșirea sa va fi 1 atunci când counter &amp;lt; out și 0 în rest.&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 4 ===&lt;br /&gt;
Implementați automatul de control al unui aparat care vinde ciocolata.&lt;br /&gt;
&lt;br /&gt;
O cafea costa 2.5 lei. Automatul accepta monezi de 50 de bani si hartii de 1 leu. Daca se depaseste suma, restul ramane in aparat si va fi folosit la urmatoarea tranzactie. Se accepta introducerea si a unei monezi si a unei bancnote in acelasi timp.&lt;br /&gt;
&lt;br /&gt;
Intrarile sistemului sunt: clock (1b), reset (1b), in_50_b (1b), in_100_b (1b); iesirile sistemului sunt: give_cioco(1b).&lt;br /&gt;
&lt;br /&gt;
Implementati automatul de control care va tine minte suma curenta si va da sau nu ciocolata in functie de aceasta. Implementati acest automat in ambele variante: Mealy si Moore.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_11_:_Automate_finite&amp;diff=8090</id>
		<title>CID aplicatii 11 : Automate finite</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_11_:_Automate_finite&amp;diff=8090"/>
		<updated>2025-05-15T12:32:46Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exemplul 2: Automat ce detecteaza fronturile crescatoare ale unui semnal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Automate finite ==&lt;br /&gt;
&lt;br /&gt;
Automatul finit este folosit pentru a descrie sisteme ce tranziteaza un numar finit de stari. Acest tip de sistem este foarte util atunci cand starile nu sunt tranzitate intr-un mod simplu, evident sau repetitiv. &lt;br /&gt;
&lt;br /&gt;
Automatul finit, numit și FSM (Finite State Machine), este un model matematic de computație, definit de următoarele elemente:&lt;br /&gt;
* O mulțime finită de simboluri de intrare, numită alfabet de intrare;&lt;br /&gt;
* O mulțime finită și nevidă de simboluri de ieșire, numită alfabet de ieșire;&lt;br /&gt;
* O mulțime finită și nevidă de stări, din care doar una, numită starea curentă, este activă la un moment dat;&lt;br /&gt;
* O stare inițială, care face parte din mulțimea stărilor;&lt;br /&gt;
* O funcție de tranziție a stărilor, care calculează starea următoare a automatului în funcție de starea curentă și de simbolul de intrare;&lt;br /&gt;
* O funcție de calcul a ieșirii, care determină simbolul de ieșire în funcție de starea curentă (în cazul automatelor de tip Moore) sau în funcție de starea curentă și de simbolul de intrare (în cazul automatelor de tip Mealy).&lt;br /&gt;
&lt;br /&gt;
[[[[Fișier:Fsm.png]]]]&lt;br /&gt;
&lt;br /&gt;
La fiecare front al ceasului, valoarea stării următoare, calculată de către CLC, va fi încărcată în registru. Dacă registrul are n biți, numărul maxim de stări care pot fi reprezentate este 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt;. Acest număr poate fi mai mic, în funcție de schema de codare a stărilor. De exemplu, pentru n = 4, folosind codarea binară se pot reprezenta cel mult 16 stări (0000, 0001, 0010, ..., 1111), în timp ce pentru codarea one-hot, în care doar un singur bit poate lua valoarea 1, se pot reprezenta 4 stări (1000, 0100, 0010, 0001).&lt;br /&gt;
&lt;br /&gt;
Pentru a reprezenta comportamentul unui automat finit, putem folosi grafuri sau organigrame, conventiile de notare depinzand de tipul automatului (Moore sau Mealy).&lt;br /&gt;
&lt;br /&gt;
== Exemple == &lt;br /&gt;
=== Exemplul 1: Automat ce detecteaza secvente de tipul 11....100....0===&lt;br /&gt;
In acest exemplu va fi implementat un automat care detecteaza secventele de tipul 11....100....0. Pentru aceasta, automatul va avea o intrare pe un bit (&amp;#039;&amp;#039;in&amp;#039;&amp;#039;, pe care va veni secventa de biti) si doua iesiri: &amp;#039;&amp;#039;detectOk&amp;#039;&amp;#039;, care semnalizeaza prin 1 ca nu a fost inca detectata o secventa ilegala si &amp;#039;&amp;#039;detectFail&amp;#039;&amp;#039;, care semnalizeaza prin 1 ca a fost detectata o secventa ilegala (un 1 dupa 0). &lt;br /&gt;
&lt;br /&gt;
Automatul va avea 3 stari: &lt;br /&gt;
* Q0 - STATE_READ1: automatul intra in aceasta stare la reset si va ramane in aceasta atata timp cat intrarea este 1 (inca nu a aparut niciun 0).&lt;br /&gt;
* Q1 - STATE_READ0: automatul intra in aceasta stare atunci cand apare pe intrare primul 0 si va ramane in aceasta atata timp cat pe intrare este 0.&lt;br /&gt;
* Q2 - STATE_ERROR: automatul intra in aceasta stare atunci cand apare un 1 dupa 0 si va ramane blocat aici pana la reset.&lt;br /&gt;
&lt;br /&gt;
Pentru a coda cele 3 stari avem nevoie de minim 2 biti: STATE_READ1 = 2&amp;#039;b00, STATE_READ0 = 2&amp;#039;b01, STATE_ERROR = 2&amp;#039;b10.&lt;br /&gt;
&lt;br /&gt;
Graful automatului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Organigrama FSM 111000.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea automatului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM1(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic detectOk,&lt;br /&gt;
    output logic detectFail&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
//Se asociaza sirurilor de biti folositi pentru codarea starilor nume ce pot fi folosite mai usor in cod.&lt;br /&gt;
//La compilare, numele vor fi inlocuite in cod cu numerele asociate la inceput.&lt;br /&gt;
localparam STATE_READ1 = 2&amp;#039;b00;&lt;br /&gt;
localparam STATE_READ0 = 2&amp;#039;b01;&lt;br /&gt;
localparam STATE_ERROR = 2&amp;#039;b10;&lt;br /&gt;
&lt;br /&gt;
logic [1:0] state, state_next;&lt;br /&gt;
&lt;br /&gt;
//registrul de stare&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= STATE_READ1;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
//circuit combinational pentru calculul starii urmatoare&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        STATE_READ1: begin&lt;br /&gt;
                         if(in == 0) state_next = STATE_READ0;&lt;br /&gt;
                     end&lt;br /&gt;
        STATE_READ0: begin&lt;br /&gt;
                         if(in == 1) state_next = STATE_ERROR;&lt;br /&gt;
                     end&lt;br /&gt;
        STATE_ERROR: state_next = STATE_ERROR;&lt;br /&gt;
        default: state_next = STATE_READ1;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//circuit combinational pentru calculul iesirilor&lt;br /&gt;
assign detectOk   = (state == STATE_READ0) || (state == STATE_READ1);&lt;br /&gt;
assign detectFail = (state == STATE_ERROR);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru FSM1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM1_TB();&lt;br /&gt;
&lt;br /&gt;
logic  clock_t;&lt;br /&gt;
logic  reset_t;&lt;br /&gt;
logic  in_t;&lt;br /&gt;
logic detectOk_t;&lt;br /&gt;
logic detectFail_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
        in_t = 1;&lt;br /&gt;
        reset_t = 1;&lt;br /&gt;
    #2  reset_t = 0;&lt;br /&gt;
    #10 in_t = 0;&lt;br /&gt;
    #10 in_t = 1;&lt;br /&gt;
    #10 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
FSM1 DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset(reset_t),&lt;br /&gt;
    .in(in_t),&lt;br /&gt;
    .detectOk(detectOk_t),&lt;br /&gt;
    .detectFail(detectFail_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Automat ce detecteaza fronturile crescatoare ale unui semnal===&lt;br /&gt;
Automatul ce detecteaza fronturile crescatoare are un singur semnal de intrare &amp;#039;&amp;#039;in&amp;#039;&amp;#039;, care reprezinta semnalul analizat si o singura iesire, &amp;#039;&amp;#039;out&amp;#039;&amp;#039;, generand pe aceasta un puls lung cat o perioada de ceas la fiecare aparitie a unui front crescator pe &amp;#039;&amp;#039;in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Vom avea nevoie de 3 stari:&lt;br /&gt;
* Q0: automatul intra in aceasta stare la reset si va ramane in aceasta atata timp cat intrarea este 0 (inca nu a aparut niciun front crescator).&lt;br /&gt;
* Q1: automatul intra in aceasta stare atunci cand apare pe intrare un front crescator. Dupa aparitia frontului crescator sunt doua posibilitati: linia ramane in 1, ceea ce duce la trecerea in starea Q2 care va duce iesirea in 0 dupa o perioada de ceas, sau linia trece in 0 dupa un ciclu de ceas, ceea ce duce la revenirea in starea Q0.&lt;br /&gt;
* Q2: automatul intra in aceasta stare atunci cand linia de intrare ramane in 1 mai mult de o perioada de ceas. Automatul va ramane in aceasta stare atata timp cat &amp;#039;&amp;#039;in&amp;#039;&amp;#039; ramane in 1 si va reveni in starea Q0 imediat ce &amp;#039;&amp;#039;in&amp;#039;&amp;#039; revine in 0.&lt;br /&gt;
&lt;br /&gt;
Graful automatului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Organigrama FSM rising edge.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea automatului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_Moore(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
localparam Q0 = 2&amp;#039;b00;&lt;br /&gt;
localparam Q1 = 2&amp;#039;b01;&lt;br /&gt;
localparam Q2 = 2&amp;#039;b10;&lt;br /&gt;
&lt;br /&gt;
logic [1:0] state, state_next;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= Q0;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        Q0: begin&lt;br /&gt;
                if(in == 1) state_next = Q1;&lt;br /&gt;
            end&lt;br /&gt;
        Q1: begin&lt;br /&gt;
                if(in == 0) state_next = Q0;&lt;br /&gt;
                if(in == 1) state_next = Q2;&lt;br /&gt;
            end&lt;br /&gt;
        Q2: begin&lt;br /&gt;
                if(in == 0) state_next = Q0;&lt;br /&gt;
            end&lt;br /&gt;
        default: state_next = Q0;&lt;br /&gt;
	endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
assign out   = (state == Q1); // iesirea depinde numai de stare =&amp;gt; Moore&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_mealy(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
localparam stare_wait_1 = 1&amp;#039;b0;&lt;br /&gt;
localparam stare_wait_0 = 1&amp;#039;b1;&lt;br /&gt;
&lt;br /&gt;
logic state, state_next;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= stare_wait_1;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        stare_wait_1: begin&lt;br /&gt;
                if(in == 1) state_next = stare_wait_0;&lt;br /&gt;
            end&lt;br /&gt;
        stare_wait_0: begin&lt;br /&gt;
                if(in == 0) state_next = stare_wait_1;&lt;br /&gt;
            end&lt;br /&gt;
        default: state_next = stare_wait_1 ;&lt;br /&gt;
	endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
	// daca pana acum semnalul a fost &amp;quot;0&amp;quot; si astept sa vina &amp;quot;1&amp;quot; si intrarea chiar vine &amp;quot;1&amp;quot; =&amp;gt; am avut front crescator&lt;br /&gt;
assign out = (state==stare_wait_1) &amp;amp; (in==1); // in apare aici =&amp;gt; dependenta iesiri de intrare =&amp;gt; Mealy&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru FSM2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_TB();&lt;br /&gt;
&lt;br /&gt;
logic  clock_t;&lt;br /&gt;
logic  reset_t;&lt;br /&gt;
logic  in_t;&lt;br /&gt;
logic out_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
        in_t = 0;&lt;br /&gt;
        reset_t = 1;&lt;br /&gt;
    #2  reset_t = 0;&lt;br /&gt;
    #10 in_t = 1;&lt;br /&gt;
    #5	in_t = 0;&lt;br /&gt;
    #10 in_t = 1;&lt;br /&gt;
    #5	in_t = 0;&lt;br /&gt;
    #10 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
FSM2_Moore DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset(reset_t),&lt;br /&gt;
    .in(in_t),&lt;br /&gt;
    .out(out_t)&lt;br /&gt;
);&lt;br /&gt;
   &lt;br /&gt;
endmodule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se poate observa ca automatele de tip Moore au un numar mai mare de stari iar automatele de tip Mealy au o logica mai complexa pentru calcularea iesirilor.&lt;br /&gt;
&lt;br /&gt;
==Exerciții==&lt;br /&gt;
=== Exercițiul 1 ===&lt;br /&gt;
Implementați un automat finit ce detectează fronturile descrescătoare. Acesta are un singur semnal de intrare &amp;#039;&amp;#039;in&amp;#039;&amp;#039;, care reprezintă semnalul analizat și o singură ieșire &amp;#039;&amp;#039;out&amp;#039;&amp;#039;, generând pe această un puls lung cât o perioadă de ceas la fiecare apariție a unui front descrescător pe &amp;#039;&amp;#039;in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Realizați implementarea SystemVerilog plecând de la graful automatului:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Graf FSM falling edge.png]]&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 2 ===&lt;br /&gt;
Implementați un automat finit ce detectează atât fronturile crescătoare, cât și pe cele descrescătoare.&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 3 ===&lt;br /&gt;
Să se implementeze un circuit care generează un semnal PWM cu un factor de umplere ce variază triungular, la fiecare front descrescător al unui semnal de intrare.&lt;br /&gt;
&lt;br /&gt;
Schema circuitului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:FSM Exercitiu.png]]&lt;br /&gt;
&lt;br /&gt;
Modulele componente ale circuitului sunt:&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FallingEdgeDetector&amp;#039;&amp;#039;&amp;#039;: Automat ce detectează fronturile descrescătoare ale semnalului de intrare.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TriangularCounter&amp;#039;&amp;#039;&amp;#039;: Automat ce generează la iesire secvența de numere 64, 128, 192, 255, 192, 128, 64.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Counter&amp;#039;&amp;#039;&amp;#039;: Numărător pe 8 biți cu reset sincron.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;COMP&amp;#039;&amp;#039;&amp;#039;: Comparator cu două intrări pe 8 biți. Ieșirea sa va fi 1 atunci când counter &amp;lt; out și 0 în rest.&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 4 ===&lt;br /&gt;
Implementați automatul de control al unui aparat care vinde ciocolata.&lt;br /&gt;
&lt;br /&gt;
O cafea costa 2.5 lei. Automatul accepta monezi de 50 de bani si hartii de 1 leu. Daca se depaseste suma, restul ramane in aparat si va fi folosit la urmatoarea tranzactie. Se accepta introducerea si a unei monezi si a unei bancnote in acelasi timp.&lt;br /&gt;
&lt;br /&gt;
Intrarile sistemului sunt: clock (1b), reset (1b), in_50_b (1b), in_100_b (1b); iesirile sistemului sunt: give_cioco(1b).&lt;br /&gt;
&lt;br /&gt;
Implementati automatul de control care va tine minte suma curenta si va da sau nu ciocolata in functie de aceasta. Implementati acest automat in ambele variante: Mealy si Moore.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_11_:_Automate_finite&amp;diff=8089</id>
		<title>CID aplicatii 11 : Automate finite</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_11_:_Automate_finite&amp;diff=8089"/>
		<updated>2025-05-12T08:29:08Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Automate finite ==&lt;br /&gt;
&lt;br /&gt;
Automatul finit este folosit pentru a descrie sisteme ce tranziteaza un numar finit de stari. Acest tip de sistem este foarte util atunci cand starile nu sunt tranzitate intr-un mod simplu, evident sau repetitiv. &lt;br /&gt;
&lt;br /&gt;
Automatul finit, numit și FSM (Finite State Machine), este un model matematic de computație, definit de următoarele elemente:&lt;br /&gt;
* O mulțime finită de simboluri de intrare, numită alfabet de intrare;&lt;br /&gt;
* O mulțime finită și nevidă de simboluri de ieșire, numită alfabet de ieșire;&lt;br /&gt;
* O mulțime finită și nevidă de stări, din care doar una, numită starea curentă, este activă la un moment dat;&lt;br /&gt;
* O stare inițială, care face parte din mulțimea stărilor;&lt;br /&gt;
* O funcție de tranziție a stărilor, care calculează starea următoare a automatului în funcție de starea curentă și de simbolul de intrare;&lt;br /&gt;
* O funcție de calcul a ieșirii, care determină simbolul de ieșire în funcție de starea curentă (în cazul automatelor de tip Moore) sau în funcție de starea curentă și de simbolul de intrare (în cazul automatelor de tip Mealy).&lt;br /&gt;
&lt;br /&gt;
[[[[Fișier:Fsm.png]]]]&lt;br /&gt;
&lt;br /&gt;
La fiecare front al ceasului, valoarea stării următoare, calculată de către CLC, va fi încărcată în registru. Dacă registrul are n biți, numărul maxim de stări care pot fi reprezentate este 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt;. Acest număr poate fi mai mic, în funcție de schema de codare a stărilor. De exemplu, pentru n = 4, folosind codarea binară se pot reprezenta cel mult 16 stări (0000, 0001, 0010, ..., 1111), în timp ce pentru codarea one-hot, în care doar un singur bit poate lua valoarea 1, se pot reprezenta 4 stări (1000, 0100, 0010, 0001).&lt;br /&gt;
&lt;br /&gt;
Pentru a reprezenta comportamentul unui automat finit, putem folosi grafuri sau organigrame, conventiile de notare depinzand de tipul automatului (Moore sau Mealy).&lt;br /&gt;
&lt;br /&gt;
== Exemple == &lt;br /&gt;
=== Exemplul 1: Automat ce detecteaza secvente de tipul 11....100....0===&lt;br /&gt;
In acest exemplu va fi implementat un automat care detecteaza secventele de tipul 11....100....0. Pentru aceasta, automatul va avea o intrare pe un bit (&amp;#039;&amp;#039;in&amp;#039;&amp;#039;, pe care va veni secventa de biti) si doua iesiri: &amp;#039;&amp;#039;detectOk&amp;#039;&amp;#039;, care semnalizeaza prin 1 ca nu a fost inca detectata o secventa ilegala si &amp;#039;&amp;#039;detectFail&amp;#039;&amp;#039;, care semnalizeaza prin 1 ca a fost detectata o secventa ilegala (un 1 dupa 0). &lt;br /&gt;
&lt;br /&gt;
Automatul va avea 3 stari: &lt;br /&gt;
* Q0 - STATE_READ1: automatul intra in aceasta stare la reset si va ramane in aceasta atata timp cat intrarea este 1 (inca nu a aparut niciun 0).&lt;br /&gt;
* Q1 - STATE_READ0: automatul intra in aceasta stare atunci cand apare pe intrare primul 0 si va ramane in aceasta atata timp cat pe intrare este 0.&lt;br /&gt;
* Q2 - STATE_ERROR: automatul intra in aceasta stare atunci cand apare un 1 dupa 0 si va ramane blocat aici pana la reset.&lt;br /&gt;
&lt;br /&gt;
Pentru a coda cele 3 stari avem nevoie de minim 2 biti: STATE_READ1 = 2&amp;#039;b00, STATE_READ0 = 2&amp;#039;b01, STATE_ERROR = 2&amp;#039;b10.&lt;br /&gt;
&lt;br /&gt;
Graful automatului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Organigrama FSM 111000.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea automatului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM1(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic detectOk,&lt;br /&gt;
    output logic detectFail&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
//Se asociaza sirurilor de biti folositi pentru codarea starilor nume ce pot fi folosite mai usor in cod.&lt;br /&gt;
//La compilare, numele vor fi inlocuite in cod cu numerele asociate la inceput.&lt;br /&gt;
localparam STATE_READ1 = 2&amp;#039;b00;&lt;br /&gt;
localparam STATE_READ0 = 2&amp;#039;b01;&lt;br /&gt;
localparam STATE_ERROR = 2&amp;#039;b10;&lt;br /&gt;
&lt;br /&gt;
logic [1:0] state, state_next;&lt;br /&gt;
&lt;br /&gt;
//registrul de stare&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= STATE_READ1;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
//circuit combinational pentru calculul starii urmatoare&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        STATE_READ1: begin&lt;br /&gt;
                         if(in == 0) state_next = STATE_READ0;&lt;br /&gt;
                     end&lt;br /&gt;
        STATE_READ0: begin&lt;br /&gt;
                         if(in == 1) state_next = STATE_ERROR;&lt;br /&gt;
                     end&lt;br /&gt;
        STATE_ERROR: state_next = STATE_ERROR;&lt;br /&gt;
        default: state_next = STATE_READ1;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//circuit combinational pentru calculul iesirilor&lt;br /&gt;
assign detectOk   = (state == STATE_READ0) || (state == STATE_READ1);&lt;br /&gt;
assign detectFail = (state == STATE_ERROR);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru FSM1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM1_TB();&lt;br /&gt;
&lt;br /&gt;
logic  clock_t;&lt;br /&gt;
logic  reset_t;&lt;br /&gt;
logic  in_t;&lt;br /&gt;
logic detectOk_t;&lt;br /&gt;
logic detectFail_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
        in_t = 1;&lt;br /&gt;
        reset_t = 1;&lt;br /&gt;
    #2  reset_t = 0;&lt;br /&gt;
    #10 in_t = 0;&lt;br /&gt;
    #10 in_t = 1;&lt;br /&gt;
    #10 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
FSM1 DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset(reset_t),&lt;br /&gt;
    .in(in_t),&lt;br /&gt;
    .detectOk(detectOk_t),&lt;br /&gt;
    .detectFail(detectFail_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Automat ce detecteaza fronturile crescatoare ale unui semnal===&lt;br /&gt;
Automatul ce detecteaza fronturile crescatoare are un singur semnal de intrare &amp;#039;&amp;#039;in&amp;#039;&amp;#039;, care reprezinta semnalul analizat si o singura iesire, &amp;#039;&amp;#039;out&amp;#039;&amp;#039;, generand pe aceasta un puls lung cat o perioada de ceas la fiecare aparitie a unui front crescator pe &amp;#039;&amp;#039;in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Vom avea nevoie de 3 stari:&lt;br /&gt;
* Q0: automatul intra in aceasta stare la reset si va ramane in aceasta atata timp cat intrarea este 0 (inca nu a aparut niciun front crescator).&lt;br /&gt;
* Q1: automatul intra in aceasta stare atunci cand apare pe intrare un front crescator. Dupa aparitia frontului crescator sunt doua posibilitati: linia ramane in 1, ceea ce duce la trecerea in starea Q2 care va duce iesirea in 0 dupa o perioada de ceas, sau linia trece in 0 dupa un ciclu de ceas, ceea ce duce la revenirea in starea Q0.&lt;br /&gt;
* Q2: automatul intra in aceasta stare atunci cand linia de intrare ramane in 1 mai mult de o perioada de ceas. Automatul va ramane in aceasta stare atata timp cat &amp;#039;&amp;#039;in&amp;#039;&amp;#039; ramane in 1 si va reveni in starea Q0 imediat ce &amp;#039;&amp;#039;in&amp;#039;&amp;#039; revine in 0.&lt;br /&gt;
&lt;br /&gt;
Graful automatului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Organigrama FSM rising edge.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea automatului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_Moore(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
localparam Q0 = 2&amp;#039;b00;&lt;br /&gt;
localparam Q1 = 2&amp;#039;b01;&lt;br /&gt;
localparam Q2 = 2&amp;#039;b10;&lt;br /&gt;
&lt;br /&gt;
logic [1:0] state, state_next;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= Q0;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        Q0: begin&lt;br /&gt;
                if(in == 1) state_next = Q1;&lt;br /&gt;
            end&lt;br /&gt;
        Q1: begin&lt;br /&gt;
                if(in == 0) state_next = Q0;&lt;br /&gt;
                if(in == 1) state_next = Q2;&lt;br /&gt;
            end&lt;br /&gt;
        Q2: begin&lt;br /&gt;
                if(in == 0) state_next = Q0;&lt;br /&gt;
            end&lt;br /&gt;
        default: state_next = Q0;&lt;br /&gt;
	endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
assign out   = (state == Q1); // iesirea depinde numai de stare =&amp;gt; Moore&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_mealy(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
localparam stare_wait_1 = 1&amp;#039;b0;&lt;br /&gt;
localparam stare_wait_0 = 1&amp;#039;b1;&lt;br /&gt;
&lt;br /&gt;
logic state, state_next;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= stare_wait_1;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        stare_wait_1: begin&lt;br /&gt;
                if(in == 1) state_next = stare_wait_0;&lt;br /&gt;
            end&lt;br /&gt;
        stare_wait_0: begin&lt;br /&gt;
                if(in == 0) state_next = stare_wait_1;&lt;br /&gt;
            end&lt;br /&gt;
        default: state_next = Q0;&lt;br /&gt;
	endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
	// daca pana acum semnalul a fost &amp;quot;0&amp;quot; si astept sa vina &amp;quot;1&amp;quot; si intrarea chiar vine &amp;quot;1&amp;quot; =&amp;gt; am avut front crescator&lt;br /&gt;
assign out = (state==stare_wait_1) &amp;amp; (in==1); // in apare aici =&amp;gt; dependenta iesiri de intrare =&amp;gt; Mealy&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru FSM2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_TB();&lt;br /&gt;
&lt;br /&gt;
logic  clock_t;&lt;br /&gt;
logic  reset_t;&lt;br /&gt;
logic  in_t;&lt;br /&gt;
logic out_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
        in_t = 0;&lt;br /&gt;
        reset_t = 1;&lt;br /&gt;
    #2  reset_t = 0;&lt;br /&gt;
    #10 in_t = 1;&lt;br /&gt;
    #5	in_t = 0;&lt;br /&gt;
    #10 in_t = 1;&lt;br /&gt;
    #5	in_t = 0;&lt;br /&gt;
    #10 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
FSM2_Moore DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset(reset_t),&lt;br /&gt;
    .in(in_t),&lt;br /&gt;
    .out(out_t)&lt;br /&gt;
);&lt;br /&gt;
   &lt;br /&gt;
endmodule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se poate observa ca automatele de tip Moore au un numar mai mare de stari iar automatele de tip Mealy au o logica mai complexa pentru calcularea iesirilor.&lt;br /&gt;
&lt;br /&gt;
==Exerciții==&lt;br /&gt;
=== Exercițiul 1 ===&lt;br /&gt;
Implementați un automat finit ce detectează fronturile descrescătoare. Acesta are un singur semnal de intrare &amp;#039;&amp;#039;in&amp;#039;&amp;#039;, care reprezintă semnalul analizat și o singură ieșire &amp;#039;&amp;#039;out&amp;#039;&amp;#039;, generând pe această un puls lung cât o perioadă de ceas la fiecare apariție a unui front descrescător pe &amp;#039;&amp;#039;in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Realizați implementarea SystemVerilog plecând de la graful automatului:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Graf FSM falling edge.png]]&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 2 ===&lt;br /&gt;
Implementați un automat finit ce detectează atât fronturile crescătoare, cât și pe cele descrescătoare.&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 3 ===&lt;br /&gt;
Să se implementeze un circuit care generează un semnal PWM cu un factor de umplere ce variază triungular, la fiecare front descrescător al unui semnal de intrare.&lt;br /&gt;
&lt;br /&gt;
Schema circuitului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:FSM Exercitiu.png]]&lt;br /&gt;
&lt;br /&gt;
Modulele componente ale circuitului sunt:&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FallingEdgeDetector&amp;#039;&amp;#039;&amp;#039;: Automat ce detectează fronturile descrescătoare ale semnalului de intrare.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TriangularCounter&amp;#039;&amp;#039;&amp;#039;: Automat ce generează la iesire secvența de numere 64, 128, 192, 255, 192, 128, 64.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Counter&amp;#039;&amp;#039;&amp;#039;: Numărător pe 8 biți cu reset sincron.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;COMP&amp;#039;&amp;#039;&amp;#039;: Comparator cu două intrări pe 8 biți. Ieșirea sa va fi 1 atunci când counter &amp;lt; out și 0 în rest.&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 4 ===&lt;br /&gt;
Implementați automatul de control al unui aparat care vinde ciocolata.&lt;br /&gt;
&lt;br /&gt;
O cafea costa 2.5 lei. Automatul accepta monezi de 50 de bani si hartii de 1 leu. Daca se depaseste suma, restul ramane in aparat si va fi folosit la urmatoarea tranzactie. Se accepta introducerea si a unei monezi si a unei bancnote in acelasi timp.&lt;br /&gt;
&lt;br /&gt;
Intrarile sistemului sunt: clock (1b), reset (1b), in_50_b (1b), in_100_b (1b); iesirile sistemului sunt: give_cioco(1b).&lt;br /&gt;
&lt;br /&gt;
Implementati automatul de control care va tine minte suma curenta si va da sau nu ciocolata in functie de aceasta. Implementati acest automat in ambele variante: Mealy si Moore.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8004</id>
		<title>CID aplicatii 5 : Exercitii cu circuite combinationale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8004"/>
		<updated>2025-03-20T20:07:59Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostiintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 1 in anii anteriori si cateva notiuni de teorie si sintaxa ajutatoare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: Parametrizare==&lt;br /&gt;
Parametrizarea este un mod de a generaliza codul scris pentru a nu fi nevoie sa scrii acelasi modul de mai multe ori doar pentru ca circuitul isi schimba o dimensiune. &lt;br /&gt;
&lt;br /&gt;
Pentru a intelege mai clar avantajele si sintaxa urmariti urmatorul exemplu:&lt;br /&gt;
&lt;br /&gt;
Fisierul sumator.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator # // &amp;lt;= diez deoarece urmeaza lista cu paramteri&lt;br /&gt;
				( // parametri &lt;br /&gt;
					parameter data_size = 4 // valoare default 4&lt;br /&gt;
					// alti parametri aici daca este nevoie, separati prin virgula&lt;br /&gt;
				)&lt;br /&gt;
				( // interfata &lt;br /&gt;
					input logic [data_size-1:0] in0, // si pot folosii parametrul &amp;quot;data_size&amp;quot; pentru dimensiunea bus-ului&lt;br /&gt;
					input logic [data_size-1:0] in1,&lt;br /&gt;
					output logic [data_size-1:0] out0&lt;br /&gt;
				);&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 + in1;				&lt;br /&gt;
				&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cand se instantiaza un modul parametrizat, se specifica valorile parametrilor astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(8)   // se genereaza un sumator pe 8b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_0&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out0)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(32)  // se genereaza un sumator pe 32b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_1&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator nume_instanta_2 // se genereaza un sumator de dimensiune default, aici 4, asa cum e scris in modulul &amp;quot;sumator&amp;quot;&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out2)&lt;br /&gt;
	);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puteti folosi parametrizarea in exercitiul 3 de mai jos. Acolo sunt 2 tipuri de multiplexoare, unul cu intrarile pe 1 bit si unul cu intrarile pe 2 biti. Poate fi scris un singur modul parametrizat care sa acopere ambele situatii.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Concatenarea==&lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara conectare a firelor sau pentru o mai buna organizare si expresivitate a codului, de multe ori este util ca fire individuale sa fie grupate impreuna sau ca un bus de mai multi biti sa fie separat in fire individuale. Acest lucru se face folosind concatenarea, prin simbolurile &amp;quot;{ }&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Un exemplu de folosire a concatenarii este oferit mai jos.&lt;br /&gt;
Un sumator pe 8b are rezultatul pe maxim 9b, in cazul in care ambele numere sunt mari. Astfel apare un bit de carry out. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator ( &lt;br /&gt;
            input logic [7:0] in0,&lt;br /&gt;
            input logic [7:0] in1,&lt;br /&gt;
            output logic [7:0] out0,&lt;br /&gt;
            output logic carry_out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign {carry_out,out0} = in0 + in1; // fac suma intre in0 si in1 iar rezultatul il pun pe cei 9b alcatuiti din: 1b carry_out si 8b out0, in ordinea asta&lt;br /&gt;
&lt;br /&gt;
endmodule       &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Se pot concatena oricat de multe semnale, puse in &amp;quot;{ }&amp;quot; si separate prin virgula. Atentie la dimensiunile firelor care se concateneaza.&lt;br /&gt;
&lt;br /&gt;
Se poate de asemenea face concatenare si la dreapta egalului, astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fir_pe_10_b = {fir_pe_3b,fir_pe_5b,fir_pe_1b,fir_pe_1b};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In exemplul anterior ultimi 2b ai &amp;quot;fir_pe_10_b&amp;quot; vor avea mereu aceeasi valoare, provenind din acelasi fir. Sintaxa SystemVerilog permite asta.&lt;br /&gt;
&lt;br /&gt;
Puteti folosii concatenarea, in exercitiul 2, la flag-ul de overflow.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Constante ca intrari in circuite==&lt;br /&gt;
In cazul in care se doreste scrierea unor constante la intrarea unor module, acestea se pun direct intre paranteze la instantiere. &lt;br /&gt;
De exemplu, pentru multiplexorul de jos din subiectul &amp;quot;alu structural&amp;quot;, intrarea &amp;quot;in3&amp;quot; este conectata la valoarea &amp;quot;1&amp;quot;. Sintaxa pentru aceasta este: &amp;quot;.in3(1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: &amp;quot;_&amp;quot;==&lt;br /&gt;
Simbolul &amp;quot;_&amp;quot; (underscore) este ignorat de SystemVerilog si ajuta vizual la citirea semnalelor pe mai multi biti. De exemplu 16&amp;#039;b1010010111110000 este identic cu 16&amp;#039;b1010_0101_1111_0000, al doilea fiind totusi mai usor de citit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 0: Repararea erorilor===&lt;br /&gt;
Arhiva de mai jos contine mai multe proiecte in Vivado, fiecare avand cate o eroare de sintaxa sau de logica. In vederea aprofundari cunostiintelor voastre (si pentru lucrarea de saptamana urmatoare), incercati sa le parcurgeti si sa rezolvati toate problemele. &lt;br /&gt;
Pe langa proiecte in sine, in arhiva se afla si un fisier text cu o introducere, rezolvarile si explicatiile pentru fiecare situatie.&lt;br /&gt;
&lt;br /&gt;
[https://drive.google.com/file/d/1cNTpQC54_JEeSk8SxgHTEdGtobCn_-EI/view?usp=drive_link Arhiva_proiecte_cu_erori.zip]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: ALU - descriere comportamentala===&lt;br /&gt;
Descrieți comportamental o unitate aritmetico-logică (ALU) care are la intrare 2 numere binare de câte 8 biți și poate calcula următoarele funcții:&lt;br /&gt;
:- suma celor două numere&lt;br /&gt;
:- diferența celor două numere&lt;br /&gt;
:- operații logice bit cu bit (bitwise): SI, SAU, XOR și inversele lor&lt;br /&gt;
:- operandul din stanga trece neschimbat&lt;br /&gt;
:- operandul din dreapta trece neschimbat&lt;br /&gt;
:- numărul din stânga este deplasat la stânga cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
:- numărul din stânga este deplasat la dreapta cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
&lt;br /&gt;
Funcția executată la un anumit moment este determinată de configurația binară de pe intrarea de comandă (function).&lt;br /&gt;
&lt;br /&gt;
ALU are de asemenea intrare de carry și ieșire de carry, plus alte două ieșiri - indicatori - pentru cazurile când rezultatul este zero și când cei doi operanzi sunt egali.&lt;br /&gt;
&lt;br /&gt;
Intrarea de control va fi facuta pe 4 biti ca sa permita existenta a 16 operatii posibile. Fiecare numar de pe intrarea de control (combinatie de 0 si 1) va reprezenta o operatie din cele de mai sus. Scrierea se va face folosind un bloc &amp;quot;case&amp;quot; in functie de aceasta intrare. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: ALU - descriere structurala===&lt;br /&gt;
 &lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/8f/Subiect_big_alu.pdf subiect_alu.pdf]&lt;br /&gt;
	&lt;br /&gt;
Daca se doreste selectarea doar a anumitor biti dintr-un bus (cum se vrea din instruction) acest lucru se poate face in 2 feluri:&lt;br /&gt;
&lt;br /&gt;
a) cu fir aditional:&lt;br /&gt;
:&amp;#039;&amp;#039;wire [1:0] fir_aditional1;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;assign fir_aditional1 = instruction[11:10];&amp;#039;&amp;#039;&lt;br /&gt;
:// apoi la instantiere: &amp;#039;&amp;#039;.sel(fir_aditional1),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
b) direct in instantiere;&lt;br /&gt;
:la instantierea celor 2 mux4 din stanga, direct: &lt;br /&gt;
::&amp;#039;&amp;#039;.sel(instruction[11:10]),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie mai putin (a nu face toate modulele de calcul separat + instantierea lor) si pentru ca e vorba de operatii simple, se poate pune operatia cu assign direct in top pe un fir declarat acolo, sau si mai prescurtat, direct operatia dorita cand se intantiaza modulul in care aceasta intra. De exemplu, pentru operatia de shift la dreapta care intra in primul multiplexor, se poate pune:  &amp;quot;.in0(data0 &amp;gt;&amp;gt; data1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3:===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/3/3a/Subiect_muxes.pdf subiect_muxes.pdf]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4:===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2e/Subiect_rom_luts.pdf rom_luts.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Sumator cu reprezentare in cifre zecimale===&lt;br /&gt;
Proiectati si verificati un sumator zecimal pentru numere cu 2 cifre&lt;br /&gt;
&lt;br /&gt;
Modulul de top (Figura 1) este alcatuit din 2 blocuri de tip &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;. Fiecare bloc aduna cifrele de pe aceasi pozitie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 1&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
   Top level&lt;br /&gt;
&lt;br /&gt;
[[Fișier: bcdsum.png]]&lt;br /&gt;
&lt;br /&gt;
Blocul &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; (Figura 2) este alctuit din 4 blocuri, 2 sumatoare binare pe 4 biti (de tip &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039;), o instanta de &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039; si un multiplexor elementar mux2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 2&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
   Blocul DIGIT SUM &lt;br /&gt;
&lt;br /&gt;
[[Fișier: digit.png]]&lt;br /&gt;
&lt;br /&gt;
Primul sumator aduna cifrele din domeniul [0...9] avand un rezultat intre [0 ... 18] &lt;br /&gt;
&lt;br /&gt;
Comparatorul are la iesire 1 daca rezultatul este mai mare decat 9.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mic decat 9, acesta este trimis in mod direct la iesirea &amp;#039;&amp;#039;&amp;#039;digit&amp;#039;&amp;#039;&amp;#039; a blocului &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mare decat 9, o crectie este necesara si se aduna 6 la rezultat.&lt;br /&gt;
&lt;br /&gt;
Comparatorul cu valoarea 9 este descris structural din porti in figura de mai jos: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 3&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
   the comparator &lt;br /&gt;
&lt;br /&gt;
[[Fișier: cmp.png]]&lt;br /&gt;
&lt;br /&gt;
Testbench-ul va genera stimuli pentru &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
Intrarea b0 a &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; se schimba la fiecare 5 pasi de simulare .&lt;br /&gt;
&lt;br /&gt;
b1, a0 si a1 se schimba sincron cu b0 ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: teststimuli.png]]&lt;br /&gt;
&lt;br /&gt;
Cerinte:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039;- descris structural la nivel de porti ca in Figura 3.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039; descris comportamental cu un assign continuu.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;mux&amp;#039;&amp;#039;&amp;#039; descris comportamental cu always.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; descris strctural ca in Figura 2.&lt;br /&gt;
# modulul de top numit &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039;, descris structural ca in Figure 1.&lt;br /&gt;
# modulul de testbench, &amp;#039;&amp;#039;&amp;#039;bcdsum_tb&amp;#039;&amp;#039;&amp;#039;, instantiaza &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; cu numele &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# in testbench, generati stimuli pentru intrarile circuitului testat.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6:===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/9/92/Cid_L1_codor_Cezar.pdf Codor_Cezar.pdf]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Cid_L1_codor_Cezar.pdf&amp;diff=8003</id>
		<title>Fișier:Cid L1 codor Cezar.pdf</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Cid_L1_codor_Cezar.pdf&amp;diff=8003"/>
		<updated>2025-03-20T20:06:48Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=8002</id>
		<title>CID aplicatii 2 : Instantiere si porti logice</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=8002"/>
		<updated>2025-03-13T11:26:43Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exemplul 2: NAND2 din AND2 si NOT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie: incapsulare si instantiere==&lt;br /&gt;
Unitatile constructive de baza din care se formeaza circuitele digitale se numesc porti logice. Acestea implementeaza functii logice si prin conectarea mai multor astfel de circuite simple complexitatea unui circuit poate creste pana la nivelul procesoarelor actuale. Pentru a putea controla cresterea complexitatii in proiectarea unui circuit de dimensiuni mari se folosesc 2 concepte cheie: &lt;br /&gt;
&lt;br /&gt;
1) incapsularea functiei dorite intr-un modul&lt;br /&gt;
&lt;br /&gt;
2) instantierea unor module mai mici si asamblarea acestora pentru a forma un modul mai mare. &lt;br /&gt;
&lt;br /&gt;
Incapsularea se refera la a grupa elementele ce alcatuiesc o anumita functionalitate intr-un modul. Aceste elemente pot la randul lor sa fie alte module.&lt;br /&gt;
Instantierea (asemanator cu POO) se refera la a apela un modul deja scris pentru a fi folosit efectiv in circuitul curent. &lt;br /&gt;
Pentru a face o analogie cu programarea, cand se declara o variabila (sau un obiect), tipul variabilei este echivalent cu modulul si numele ei este numele instantei.&lt;br /&gt;
&lt;br /&gt;
Pentru a intelege aceste concepte se da circuitul de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_instantiere.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1) Notatie aici: Numele modulului este scris in interior. &lt;br /&gt;
&lt;br /&gt;
2) Notatie aici: Numele instantei este scris deasupra.&lt;br /&gt;
&lt;br /&gt;
3) Idee fundamentala: prin instantierea si incapsularea unor circuite simple, mici, apar circuite mai complexe.&lt;br /&gt;
&lt;br /&gt;
4) Idei esentiale (daca vreuna e neclara consultati cadrul didactic): &lt;br /&gt;
&lt;br /&gt;
:a) &amp;quot;modul_2&amp;quot; este instantiat o singura data in tot proiecul, iar instanta se cheama &amp;quot;x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:b) &amp;quot;modul_2&amp;quot; are o intrare numita &amp;quot;in0&amp;quot; si o iesire numita &amp;quot;out0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:c) &amp;quot;modul_2&amp;quot; este instantiat in cadrul &amp;quot;modul_6&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:d) Modulul cel mai mare, ce cuprinde toata functionalitatea dorita a sistemului (aici &amp;quot;modul_6&amp;quot;) se numeste uzual top.&lt;br /&gt;
&lt;br /&gt;
:e) Instanta top-ului care apare atunci cand se doreste testarea sa in simulare intr-un testbench (tb) se numeste uzual DUT (design under test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:f) &amp;quot;modul_0&amp;quot; apare instantiat de 3 ori. Circuitul final, cuprinde 3 subcircuite de tip &amp;quot;modul_0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:g) La nivel de top, instanta sa se cheama &amp;quot;b&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
:h) La nivel de &amp;quot;modul_5&amp;quot;, cele 2 instante se cheama &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:i) &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot; sunt 2 circuite fizice diferite chiar daca ambele sunt de tipul &amp;quot;modul_0&amp;quot;. Fiind instante ale aceluiasi modul, deci identice in alcatuire, luate separat ele fac acelasi lucru. Luate in contextul lui &amp;quot;modul_5&amp;quot;, &amp;quot;a&amp;quot; genereaza datele de pe firul &amp;quot;w0&amp;quot; si &amp;quot;c&amp;quot; genereaza datele pentru iesire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:j) circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_1&amp;quot; (instantiat in &amp;quot;modul_5&amp;quot;) este complet diferit de circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_0&amp;quot; (instantiat in top). Este permis ca ele sa aiba acelasi nume (cele 2 instante) deoarece se afla in locatii diferite. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:k) Identic, mai multe module au o intrare numita &amp;quot;in_0&amp;quot;. La sinteza circuitului nu se face confuzie intre acestea deoarece fiecare e vazut la nivelul altei instante.&lt;br /&gt;
&lt;br /&gt;
:l) Identic, firele de legatura &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:m) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w2&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;b&amp;quot; la intrarea &amp;quot;in2&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:n) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;x&amp;quot; la intrarea &amp;quot;in1&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:o) La nivelul &amp;quot;modul_5&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea instantei &amp;quot;b&amp;quot; la intrarea instantei &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:Pentru claritatea desenului, respectivele intrari si iesiri nu au fost denumite. In cod este obligatoriu ca ele sa fie definite si denumite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:p) La nivelul &amp;quot;top&amp;quot;, &amp;quot;in0&amp;quot;,&amp;quot;in1&amp;quot;,&amp;quot;in2&amp;quot;,&amp;quot;in3&amp;quot;,&amp;quot;in4&amp;quot; si &amp;quot;out0&amp;quot; formeaza interfata modulului (semnalele care intra sau ies din modul).&lt;br /&gt;
&lt;br /&gt;
:q) La nivelul &amp;quot;top&amp;quot;, &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;, &amp;quot;w2&amp;quot; sunt fire interne de legatura.&lt;br /&gt;
&lt;br /&gt;
:r) La nivelul &amp;quot;top&amp;quot;, firul &amp;quot;in3&amp;quot; este conectat ca intrare pentru 3 submodule.&lt;br /&gt;
&lt;br /&gt;
==Teorie: testarea circuitelor==&lt;br /&gt;
Pentru a se testa functionarea corecta a circuitului final, acesta este instantiat intr-un modul numit &amp;quot;test_bench&amp;quot; sau &amp;quot;tb&amp;quot;. Acest modul este folosit strict in simulare. &lt;br /&gt;
Testarea unui circuit are loc conform schemei urmatoare: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_tb.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Generarea datelor de intrare se va face asemanator cu laboratorul 1.&lt;br /&gt;
&lt;br /&gt;
Voi veti avea rolul modelului ideal si al comparatorului datelor de iesire, uitandu-va la datele de intrare veti calcula iesirea corecta si apoi veti compara aceasta valoare cu raspunsul circuitului ce se testeaza.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In cazul unui sistem automat, se genereaza mesaje de eroare sau mesaje ca functionarea este in regula.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Observatie: proiectarea si verificarea sunt 2 domenii diferite, firmele avand departamente separate pentru acestea. &lt;br /&gt;
&lt;br /&gt;
Proiectarea/Design se ocupa cu scrierea in Verilog/SystemVerilog a modului de top si toate modulele ce se afla in acesta, avand ca scop final realizarea fizica pe placa a unui circuit. &lt;br /&gt;
&lt;br /&gt;
Verificarea se ocupa de scrierea in SystemVerilog (limbaj format din Verilog cu concepte de POO) a modului de testbench si generarea de stimuli si scenarii care sa testeze functionarea design-ului.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: porti logice==&lt;br /&gt;
Portile logice folosite uzual, impreuna cu tabelele lor de adevar si reprezentarea grafica sunt date mai jos.&lt;br /&gt;
&lt;br /&gt;
Se folosesc porti logice cu 1 sau 2 intrari, cele cu mai mult de 2 intrari fiind construite din acestea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tip !! Simbol !! Tabel de adevăr !! Tip !! Simbol !! Tabel de adevăr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Buffer/Repetor&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:Buffer_gate.png|Buffer symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOT&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:not.png|NOT symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || NOT A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;AND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:and.png|AND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A AND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NAND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nand.png|NAND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NAND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;OR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:or.png|OR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A OR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nor.png|NOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xor.png|XOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XNOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xnor.png|XNOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XNOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Despre FPGA==&lt;br /&gt;
FPGA-ul (Field-Programmable Gate Array) este un circuit programabil, capabil sa implementeze circuite definit de utilizator. El este format dintr-o matrice de blocuri programabile, interconectate intre ele printr-o serie de conexiuni la randul lor programabile.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cand se doreste implementarea unui circuit pe FPGA, acesta urmeaza urmatoarele etape: &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Elaborarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care codul SystemVerilog este transformat intr-un circuit la nivel de porti si registre (netlist) si este independent de modelul de FPGA folosit. &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Sinteza&amp;#039;&amp;#039;&amp;#039; este procesul în care se realizează transformarea circuitului descris într-un netlist dependent de tehnologie. Se vor folosi la acest pas primitivele disponibile pe FPGA.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Implementarea&amp;#039;&amp;#039;&amp;#039; este procesul în care se preia netlist-ul ce conține primitivele FPGA și modul lor de interconectare realizat la pasul de sinteză și se realizează maparea lor efectivă în FPGA (place and route).&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Generarea Bitstream-ului&amp;#039;&amp;#039;&amp;#039; este procesul prin care informatiile din implementare sunt asamblate intr-un singur fisier.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Programarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care fisierul generat anterior este trimis efectiv catre placa cu FPGA (prin USB) unde determina modificarea valorilor si conexiunilor interne din aceasta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O introducere mai detaliata poate fi gasita aici : [[FPGA - Introducere]].&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Fpgaimg.PNG|600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Pentru a putea controla circuitul propus si a putea vedea rezultatele, intrarile si iesirile (input si output din module) in/din acesta trebuie conectate la pini fizici ai FPGA-ului care sunt conectati la butoane/switch-uri/leduri.&lt;br /&gt;
* Conexiunile dintre butoane/switch-uri si pinii FPGA sunt fixe. La fel si cele intre pinii FPGA si LED-uri. (in functie de PCB)&lt;br /&gt;
* Conexiunile dintre porturile modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; si pinii FPGA sunt configurabile. (in functie de noi, prin fisierul XDC)&lt;br /&gt;
* Legarea porturilor modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; la pinii fizici ai FPGA se realizeaza prin configurarea conexiunilor din FPGA conform contrangerilor de I/O pe care le vom mentiona in proiect, inainte de sinteza.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 1: Analiza circuitelor cu porti===&lt;br /&gt;
Fie urmatorul circuit alcatuit din porti logice:&lt;br /&gt;
 [[Fișier:Mux2_schema_interna_2.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Se doreste exprimarea circuitului de mai sus ca formula de tip: iesire = f(intrari). &lt;br /&gt;
&lt;br /&gt;
Pentru asta, abordarea consta in a porni de la iesire si a merge pas cu pas catre intrari, asa cum este exemplificat mai jos. Se vor folosi simbolurile &amp;quot;~&amp;quot; pentru NOT, &amp;quot;&amp;amp;&amp;quot; pentru AND, &amp;quot;|&amp;quot; pentru OR.&lt;br /&gt;
:pas1: out0 = ?&lt;br /&gt;
:pas2: out0 = w1 | w2&lt;br /&gt;
:pas3: out0 = w1 | ( ? )&lt;br /&gt;
:pas4: out0 = w1 | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas5: out0 = ( ? ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas6: out0 = ( in0 &amp;amp; w0 ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas7: out0 = ( in0 &amp;amp; ( ? ) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas8: out0 = ( in0 &amp;amp; (~sel) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: NAND2 din AND2 si NOT===&lt;br /&gt;
In urmatorul exemplu se implementeaza o poarta NAND din o poarta AND si o poarta NOT. &lt;br /&gt;
&lt;br /&gt;
Codul de mai jos exemplifica ideea de instantiere si contine comentarii legate de sintaxa SystemVerilog necesara.&lt;br /&gt;
&lt;br /&gt;
In mod uzual fisierele sunt denumite dupa modulul ce se afla in ele, in fiecare fisier fiind un singur modul.&lt;br /&gt;
&lt;br /&gt;
Schema circuitul care se doreste a fi creat este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_exemplu_rezolvat.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii NOT (fisierul not_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
// comentarii cu &amp;quot;//&amp;quot; sau cu /* .... */ ;&lt;br /&gt;
/* &lt;br /&gt;
	ca in c/c++ &lt;br /&gt;
*/ &lt;br /&gt;
&lt;br /&gt;
module not_gate	// cuvant cheie &amp;quot;module&amp;quot; apoi numele modulului (asemanator clase din c++)&lt;br /&gt;
	( // intre paranteze se pune interfata (firele care intra sau ies din modul)&lt;br /&gt;
		input logic in0,         // in0 este o intrare =&amp;gt; input&lt;br /&gt;
		output logic out0	// out0 este o iesire =&amp;gt; output&lt;br /&gt;
	); // aici &amp;quot;;&amp;quot; sa nu il uitati&lt;br /&gt;
&lt;br /&gt;
assign out0 = ~in0;	// cuvant cheie assign; &lt;br /&gt;
					// semnalele pot lua valoare prin assign&lt;br /&gt;
					// ~ e semnul pentru negatie pe biti (ca in c/c++)&lt;br /&gt;
&lt;br /&gt;
endmodule // cuvant cheie &amp;quot;endmodule&amp;quot;. orice module se inchide cu endmodule.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii AND (fisierul and_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and_gate&lt;br /&gt;
	(&lt;br /&gt;
		input logic in0,	// aici sunt 2 intrari &lt;br /&gt;
		input logic in1,	&lt;br /&gt;
		output logic out0&lt;br /&gt;
	); // nu conteaza ordinea in care sunt puse intrarile si iesirile.&lt;br /&gt;
			// uzual si pentru usurinta se ordoneaza si grupeaza dupa functionalitate&lt;br /&gt;
			// in cazul de mai sus, am pus intai intrarile, apoi iesirile.&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 &amp;amp; in1; // operatia propriu zisa &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului top (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic a,&lt;br /&gt;
		input logic b,&lt;br /&gt;
		output logic c&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic w0;    //declarat un fir intern de legatura &lt;br /&gt;
    &lt;br /&gt;
and_gate and_gate_0	// instantiere: nume_modul nume_instanta (asemanator int x din c/c++)&lt;br /&gt;
	(&lt;br /&gt;
		.in0(a), // la intrarea &amp;quot;in0&amp;quot; a instantei &amp;quot;and_gate_0&amp;quot;  se conecteaza firul &amp;quot;a&amp;quot; din top&lt;br /&gt;
		.in1(b), // grija ca &amp;quot;in0&amp;quot;, &amp;quot;in1&amp;quot;, &amp;quot;out0&amp;quot; sa existe in declararea modulului &amp;quot;and_gate&amp;quot;&lt;br /&gt;
		.out0(w0) // grija ca &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;w0&amp;quot; sa existe la nivelul modulului in care se face instantierea&lt;br /&gt;
	);    &lt;br /&gt;
    &lt;br /&gt;
not_gate not_gate_0&lt;br /&gt;
	(&lt;br /&gt;
		.in0(w0), // &amp;quot;w0&amp;quot; care iese din &amp;quot;and_gate_0&amp;quot; intra in &amp;quot;not_gate_0&amp;quot;&lt;br /&gt;
		.out0(c) // &amp;quot;c&amp;quot; care iese din &amp;quot;not_gate_0&amp;quot; iese din modulul &amp;quot;top&amp;quot; (e iesire in interfata de sus)&lt;br /&gt;
	);   // se poate scrie si &amp;quot;.in0(w0),.out0(c)&amp;quot; dar se prefera fiecare fir pe randul sau (lizibilitate si loc de comentarii pt design-uri complexe)&lt;br /&gt;
	// Observatie: la varianta de mai sus de instantiere, nu conteaza ordinea firelor. &lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
not_gate not_gate_0		&lt;br /&gt;
	(				// se poate instantia si in forma prescurtata ca aici &lt;br /&gt;
		w0,				// in acest caz se pun conexiunile in ordinea in care sunt declarate intrarile si iesirile din modul&lt;br /&gt;
		c	// NU se recomanda stilul asta de instantiere&lt;br /&gt;
	); 			// apar greseli frecvent la ordinea firelor si la numarul lor, &lt;br /&gt;
*/				// mai ales daca modulul e complex si are multe intrari si intrari&lt;br /&gt;
 &lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Echivalent se pot folosi si &amp;quot;primitive&amp;quot; SystemVerilog pentru scrierea top-ului.&lt;br /&gt;
&lt;br /&gt;
Primitivele sunt circuite care exista deja in limbaj, folosite atunci cand se doreste o descriere structurala a circuitului.&lt;br /&gt;
&lt;br /&gt;
In instantiere acestora, iesirea se pune prima, urmata de intrari.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; daca se doreste scrierea acestor porti de catre voi (ca mai sus), numele modulului nu trebuie sa fie un cuvant cheie ocupat de primitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v2&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
  &lt;br /&gt;
logic w0;&lt;br /&gt;
&lt;br /&gt;
and and_gate_0(w0,a,b);	// primitiva pentru poarta and&lt;br /&gt;
not not_gate_0(c,w0);  	// primitiva pentru poarta not&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fiind un modul simplu, intreaga functionalitate putea fi scrisa la nivel de &amp;quot;top&amp;quot; si simplificat ca mai jos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v3.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v3&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
   &lt;br /&gt;
assign c = ~ (a &amp;amp; b); // a si b, negate&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Testarea circuitul se face printr-un testbench, acesta fiind:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea testbench-ului (fisierul top_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module top_tb(); // din/in tb nu intra si iese nimic. niciodata.&lt;br /&gt;
&lt;br /&gt;
logic a_tb;	&lt;br /&gt;
logic b_tb;	&lt;br /&gt;
logic c_tb;	&lt;br /&gt;
&lt;br /&gt;
top dut	// instantierea modulului de tip &amp;quot;top&amp;quot; sub numele &amp;quot;dut&amp;quot; &lt;br /&gt;
	(&lt;br /&gt;
		.a(a_tb),&lt;br /&gt;
		.b(b_tb),&lt;br /&gt;
		.c(c_tb)&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin // in loc de { ... } din c/c++, in SystemVerilog se pune begin ... end &lt;br /&gt;
	#10;		// dupa 10 unitati de timp &lt;br /&gt;
	a_tb = 0;		// a_tb ia valoarea 0&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;		// dupa inca 10 unitati de timp, deci in total la 20&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	&lt;br /&gt;
	#20 $stop();	// oprirea simularii &lt;br /&gt;
end //end pentru initial &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formele de unda rezultate din simulare se pot vedea mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:exemplu_rezolvat_nand_forme_de_unda.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In chenarul verde se pot observa instantele din simulare. &lt;br /&gt;
&lt;br /&gt;
Daca se doreste adaugarea de semnale noi pentru a fi vazute, se selecteaza modulul instantiat in care acestea se afla (chenar verde). &lt;br /&gt;
&lt;br /&gt;
Apoi, din chenarul rosu se aleg semnalele si se adauga prin click dreapta-&amp;gt;add to wave window. &lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara vizualizare, semnalele se pot grupa asa cum se vede in chenarul mov prin click dreapta-&amp;gt;new group.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se observa o functionare corecta circuitului, acesta fiind o poarta NAND. El scoate &amp;quot;0&amp;quot; cand ambele semnale de intrare sunt &amp;quot;1&amp;quot; si scoate &amp;quot;1&amp;quot; in rest.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea circuitului pe FPGA&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dupa ce circuitul a fost testat in simulare, se doreste punerea sa fizica pe placa FPGA. Pentru aceasta, se tine cont de urmatoarele.&lt;br /&gt;
&lt;br /&gt;
* Pentru a controla intrarile &amp;#039;&amp;#039;a&amp;#039;&amp;#039; si &amp;#039;&amp;#039;b&amp;#039;&amp;#039; ale circuitului &amp;#039;&amp;#039;&amp;#039;top&amp;#039;&amp;#039;, va trebui sa le conectam prin intermediul conexiunilor configurabile ale FPGA-ului la pini ce sunt mai departe conectati fizic la dispozitive ce pot controla valorile semnalelor (switch-uri, butoane).&lt;br /&gt;
* Pentru a observa valoarea iesirii, vom conecta semnalul de iesire &amp;#039;&amp;#039;c&amp;#039;&amp;#039;la un dispozitiv de observare, cum ar fi un LED, care va fi aprins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 1 si stins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 0.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:NAND2 FPGA.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru a realiza conectarea porturilor modulului &amp;#039;&amp;#039;top&amp;#039;&amp;#039; la pinii fizici ai FPGA ce sunt conectati mai departe la componentele de pe placa, va trebui sa specificam in utilitarul de sinteza maparea porturilor la acestia. Maparea se realizeaza prin mentionarea codurilor pinilor la care dorim conexiunea si poata numele de &amp;#039;&amp;#039;&amp;#039;constrangeri de I/O&amp;#039;&amp;#039;&amp;#039;. Aceste coduri sunt mentionate in documentatia placii de dezvoltare cu FPGA (in cazul nostru, Boolean Board) si pot fi regasite si in pagina [[Boolean Board - Pinout]].&lt;br /&gt;
&lt;br /&gt;
Conform schemei, la acest exemplu avem nevoie de codurile pinilor conectati mai departe la Switch0, Switch1 si LED0.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Daca intrarile si iesirile ar fi semnale pe mai multi biti, fiecare bit al intrarilor va fi conectat la cate un switch/buton si fiecare bit al iesirii va fi conectat la un LED. Acest lucru este necesar deoarece switch-urile/butoanele pot avea doar doua stari (0 si 1) si astfel pot controla un singur bit. La fel, un LED poate avea doar doua stari (0 - stins si 1 - aprins) si poate afisa starea unui singur bit.&lt;br /&gt;
&lt;br /&gt;
Dupa ce ati extras codurile necesare, urmati pasii descrisi in [[Tutorial_Vivado|tutorialul Vivado]]. &lt;br /&gt;
&lt;br /&gt;
Dupa programarea cu succes a placii, puteti testa functionalitatea circuitului prin modficarea valorilor switch-urilor si observarea starii LED-ului.&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
Pentru urmatoarele exercitii se doreste atat testarea designurilor prin simulare cat si punerea acestora pe placa. Legat de placa, intrarile vor fi conectate la butoane, iar iesirile la leduri. Se va consulta tabelul cu pini disponibili ([[Boolean Board - Pinout]].).&lt;br /&gt;
&lt;br /&gt;
Exista moduri mai rapide de a scrie functionalitatea dorita (vezi exemplu), dar tema principala a acestui laborator este instantierea, asa ca sunteti rugati sa respectati desenele si sa instantiati fiecare poarta individual.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: AND4 din AND2=== &lt;br /&gt;
&lt;br /&gt;
Acest exercitiu arata cum se construieste o poarta AND cu 4 intrari din porti AND mai simple, cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca toate intrarile sunt &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_and4.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: OR4 din OR2===&lt;br /&gt;
&lt;br /&gt;
Asemanator cu exercitiul anterior, se poate construi si o poarta or cu 4 intrari din porti or cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca oricare din intrari (cel putin una) este &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_or4_din_or2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: AND4 din AND2 aranjat in cascada (nu arbore)===&lt;br /&gt;
&lt;br /&gt;
In multe cazuri, aceeasi functionalitate poate fi atinsa prin circuite care arata diferit. &lt;br /&gt;
O alta varianta de a face o poarta AND cu 4 intrari este prezentata mai jos. &lt;br /&gt;
&lt;br /&gt;
Comparati cele 2 variante. &lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2_v2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: AND4 din NAND2===&lt;br /&gt;
&lt;br /&gt;
Orice poarta logica de baza poate fi construita doar din porti NAND sau doar din porti NOR. &lt;br /&gt;
&lt;br /&gt;
Desenati si implementati circuitul pentru o poarta AND4 din porti NAND cu 2 intrari. &lt;br /&gt;
&lt;br /&gt;
Tip: Incercati intai sa generati o poarta AND2 din NAND2.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: AND4 pe 4b din AND4 pe 1b===&lt;br /&gt;
&lt;br /&gt;
Se pot face operatii logice si pe mai multi biti deodata prin punerea in paralel a mai multor porti cu o singura iesire.&lt;br /&gt;
	Exemplu :&lt;br /&gt;
		pentru intrarile 0011 si 1110 iesirea va fi 0010&lt;br /&gt;
&lt;br /&gt;
Pentru exersarea instantierii si intelegerea circuitului din spatele operatilor multibit implementati acest circuit prin instantierea a 4 porti AND4 pe 1 bit intr-o poarta AND4 pe 4 biti.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v1.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns):&lt;br /&gt;
 &lt;br /&gt;
[[Fișier:Wavedrom_and4_4b.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
Exista si un mod mai rapid si simplu de a scrie aceasta functionalitate, grupand intrarile si iesirile in &amp;quot;bus&amp;quot;-uri, ca in codul de mai jos.&lt;br /&gt;
Acest mod de a grupa firele este desenat mai jos.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Fisierul and4_4b.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and4_4b&lt;br /&gt;
	(&lt;br /&gt;
		input logic [3:0] in0,	// in0 are 4b, de la bit 3 la bit 0 inclusiv &lt;br /&gt;
		input logic [3:0] in1,	// se noteaza msb:lsb (most significant bit: least significant bit) (echivalent cu conceptul de cifra sutelor, cifra unitatilor, pt binar)&lt;br /&gt;
		input logic [3:0] in2,&lt;br /&gt;
		input logic [3:0] in3,&lt;br /&gt;
		output logic [3:0] out0&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
assign out0 = in0 &amp;amp; in1 &amp;amp; in2 &amp;amp; in3;&lt;br /&gt;
	&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Desenati schemele logice pentru urmatoarele circuite:===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;a) Schema 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema1 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f, g;&lt;br /&gt;
	&lt;br /&gt;
	logic w1;&lt;br /&gt;
	logic w2;&lt;br /&gt;
	&lt;br /&gt;
	and P1 ( w1, a, c );&lt;br /&gt;
	or P2 ( f, w1, w2, d);&lt;br /&gt;
	not P3 (w2, b);&lt;br /&gt;
	and P4 (g, w1, b, d);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observatie: In versiunea veche de verilog (si s-a pastrat si in cea curenta), se pot specifica directiile porturilor si in exteriorul parantezelor, ca mai sus. &lt;br /&gt;
Aceasta scriere NU este recomandata. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;b) Schema 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema2 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f;&lt;br /&gt;
	&lt;br /&gt;
	logic w1, w2;&lt;br /&gt;
	&lt;br /&gt;
	nand P1 ( w1, a, b ), P2 (w2, c, d);&lt;br /&gt;
	and P3 ( f, w1, w2);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; asemanator cu C/C++, se pot face declaratii in aceeasi linie a mai multor &amp;quot;variabile&amp;quot;, aici fire sau instante, cum se poate vedea la w1 si w2 (ambele fiind fire) sau la P1 si P2 (ambele fiind porti nand).&lt;br /&gt;
Aceasta scriere NU este recomandata.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_3_:_Circuite_combinationale_elementare&amp;diff=8001</id>
		<title>CID aplicatii 3 : Circuite combinationale elementare</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_3_:_Circuite_combinationale_elementare&amp;diff=8001"/>
		<updated>2025-03-13T11:25:14Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exemplu - Decodorul */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Teorie==&lt;br /&gt;
Acest laborator are ca scop scrierea unor circuite combinationale simple si explorarea variantelor de sintaxa diferite ce ajung sa ofere aceeasi functionalitate. Sintaxa va fi explicata in comentariile exemplului rezolvat mai jos.&lt;br /&gt;
&lt;br /&gt;
Descrierea circuitelor in SystemVerilog se face in una din doua forme:&lt;br /&gt;
&lt;br /&gt;
:1) structurala - descrie cum un modul e alcatuit din module sau primitive mai simple&lt;br /&gt;
&lt;br /&gt;
:2) comportamentala/behavioural - descrie cum se calculeaza iesirile din intrari&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exemplu - Decodorul==&lt;br /&gt;
Decodorul este un circuit a carui iesire pe n biti are un singur bit de &amp;quot;1&amp;quot;, anume cel selectat prin singura sa intrare pe log2(n) biti. &lt;br /&gt;
Astfel, pentru un decodor cu iesire pe 8b, intrarea va avea 3b (logaritm in baza 2 din 8) si tabelul de adevar va arata astfel: &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| in(3b) || out(8b) &lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|000 || 0000_0001&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|001 || 0000_0010&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|010 || 0000_0100&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|011 || 0000_1000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|100 || 0001_0000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|101 || 0010_0000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|110 || 0100_0000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|111 || 1000_0000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Iesirea este numerotata de la bitul 7 (msb) pana la bitul 0 (lsb). Se observa ca daca intrarea are valoare &amp;quot;a&amp;quot;, singurul bit de &amp;quot;1&amp;quot; din iesire este cel de pe pozitia &amp;quot;a&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Atat in tabelul de mai sus, cat si in codul SystemVerilog poate sa apara &amp;quot;_&amp;quot; (underscore) ca sa ajute vizual la separarea/numararea cifrelor. Se foloseste in mod uzual la scrierea in binar ca sa grupeze 4b (o cifra in hexa).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Circuitul exemplu al acestui laborator va fi un decodor mai mic, cu 2 biti de intrare si 4 de iesire, avand tabelul de adevar:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| in(2b) || out(4b) &lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|00 || 0001&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|01 || 0010&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|10 || 0100&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|11 || 1000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
O varianta de schema care implementeaza acest circuit este cea de mai jos: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:w3_exemplu_rezolvat.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
In circuitul de mai sus, apare dubla negatie, respectivul semnal putand fi luat si direct de la intrare. Acest lucru se intampla din considerente electrice. Desi pe desene nu sunt trecute, fiecare poarta are si fire de alimentare si de masa. Astfel, pentru a evita fire de lungimi foarte mari sau fire care se propaga in multe intrari si probleme de cadere a tensiunilor, se folosesc astfel de buffere/repetoare. &lt;br /&gt;
&lt;br /&gt;
Codul de mai jos exemplifica moduri diferite de a exprima aceasta functionalitate.&lt;br /&gt;
El contine comentarii referitoare la sintaxa de baza SystemVerilog, necesara implementarii modulelor in diverse moduri. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor - varianta structurala din porti, cu primitive (fisierul decodor_v1.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v1&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,	// definirea intrarilor sub forma de &amp;quot;bus&amp;quot; &lt;br /&gt;
									// bus-ul de intrare se numeste &amp;quot;in&amp;quot; si este pe 2 biti: in[1], in[0]&lt;br /&gt;
									// fizic sunt 2 fire distincte, grupate pentru o mai simpla folosire.&lt;br /&gt;
		output logic [3:0] out 	// avem o iesire, numita &amp;quot;out&amp;quot; pe 4 biti.&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
logic in_0_inv;&lt;br /&gt;
logic in_1_inv;&lt;br /&gt;
logic in_0_nat;&lt;br /&gt;
logic in_1_nat;&lt;br /&gt;
&lt;br /&gt;
not not_gate_0(in_0_inv,in[0]); // aleg bitul 0 al lui in sa intre in aceasta poarta not;&lt;br /&gt;
&lt;br /&gt;
not not_gate_1(in_1_inv,in[1]); // observatie: cele 2 fire si cele 2 porti putea fi comprimate intr-un bus + poarta not pe 2 biti.&lt;br /&gt;
&lt;br /&gt;
not not_gate_2(in_0_nat,in_0_inv);&lt;br /&gt;
&lt;br /&gt;
not not_gate_3(in_1_nat,in_1_inv);&lt;br /&gt;
&lt;br /&gt;
and and_gate_0(out[0],in_1_inv,in_0_inv);&lt;br /&gt;
&lt;br /&gt;
and and_gate_1(out[1],in_1_inv,in_0_nat);&lt;br /&gt;
&lt;br /&gt;
and and_gate_2(out[2],in_1_nat,in_0_inv);&lt;br /&gt;
&lt;br /&gt;
and and_gate_3(out[3],in_1_nat,in_0_nat);&lt;br /&gt;
	&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor - varianta cu assign, urmand schema (fisierul decodor_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v2&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
	// fiecare bit din iesire calculat independent&lt;br /&gt;
assign out[0] = ~in[0] &amp;amp; ~in[1];&lt;br /&gt;
assign out[1] = in[0] &amp;amp; ~in[1];&lt;br /&gt;
assign out[2] = ~in[0] &amp;amp; in[1];&lt;br /&gt;
assign out[3] = in[0] &amp;amp; in[1];&lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu assign, cu operatorul &amp;quot;?&amp;quot; (fisierul decodor_v3.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v3&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
// operatorul &amp;quot;?&amp;quot;: identic c/c++; (conditie) ? (if_true) : (if_false);&lt;br /&gt;
&lt;br /&gt;
assign out = (in==0) ? // if in == 0 &lt;br /&gt;
				1 : // if true: out = 1 &lt;br /&gt;
				(in==1) ? // else, verifica alt if. &lt;br /&gt;
					2 : // if in !=0 si in == 1&lt;br /&gt;
					(in==2) ?&lt;br /&gt;
						4 :&lt;br /&gt;
						8; // last case in==3&lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu always cu if (fisierul decodor_v4.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v4&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out&lt;br /&gt;
	);						 &lt;br /&gt;
&lt;br /&gt;
always_comb // mereu cand se schimba orice semnal, se &amp;quot;executa&amp;quot; ce e mai jos; &lt;br /&gt;
            // always_comb genereaza un circuit combinational&lt;br /&gt;
begin	// begin si end pe post de acolade din c/c++; delimiteaza if/else si altele asemenea; inclusiv always cu totul&lt;br /&gt;
	if(in == 0)&lt;br /&gt;
		begin // nota autorului: eu prefer sa pun begin/end asa. ele se pot pune si dupa conditie sau aliniate altfel.&lt;br /&gt;
				// ^ preferinta personala legata de coding style, important e sa fiti consecventi in cum scrieti&lt;br /&gt;
		out = 1; &lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		begin&lt;br /&gt;
		if(in == 1)&lt;br /&gt;
			out = 2;	// fiind o singura instructiune, begin/end se poate omite (identic c/c++)&lt;br /&gt;
		else&lt;br /&gt;
			begin	// nota autorului: eu personal le pun mereu. in caz ca mai adaug linii in if dupa, sa fie deja puse&lt;br /&gt;
			if(in == 2)&lt;br /&gt;
				begin&lt;br /&gt;
				out = 4;&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				begin&lt;br /&gt;
				out = 8;&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
end//end pt always&lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu always cu case (fisierul decodor_v5.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v5&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
always_comb&lt;br /&gt;
begin&lt;br /&gt;
	case(in) // functioneaza ca switch/case din c/c++; sintaxa usor diferita&lt;br /&gt;
		0: // if in == 0&lt;br /&gt;
			begin&lt;br /&gt;
			out = 1;&lt;br /&gt;
			end&lt;br /&gt;
		2&amp;#039;d1: // if in == 1;	2&amp;#039;d1 se traduce: pe 2 biti, in baza zece (eng: decimal, &amp;quot;d&amp;quot;), valoarea 1&lt;br /&gt;
			begin	// pt &amp;quot;0&amp;quot; de mai sus: daca nu se pune nimic se considera in baza zece.&lt;br /&gt;
			out = 2;&lt;br /&gt;
			end&lt;br /&gt;
		2&amp;#039;b10: // if in == 2;	scris in binar &amp;quot;b&amp;quot;, 2&amp;#039;b10 =&amp;gt; adica valoarea 2(10 binar) pe 2 biti &lt;br /&gt;
			begin&lt;br /&gt;
			out = 4;&lt;br /&gt;
			end&lt;br /&gt;
		2&amp;#039;h3: // if in == 3;	scris in hexa (baza 16 &amp;quot;h&amp;quot;, se poate si &amp;quot;x&amp;quot;), fiind numar mic, nu se vede diferenta fata de zecimal.&lt;br /&gt;
			begin&lt;br /&gt;
			out = 8;&lt;br /&gt;
			end&lt;br /&gt;
		default: // daca in == un caz netrat; &lt;br /&gt;
			begin // aici inutil pt ca am tratat toate cazurile posibile; pus ca exemplu de sintaxa &lt;br /&gt;
			out = 0;&lt;br /&gt;
			end&lt;br /&gt;
	endcase // orice &amp;quot;case&amp;quot; se inchide cu &amp;quot;endcase&amp;quot;&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;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu assign comportamental  (fisierul decodor_v6.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v6&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign out = 1 &amp;lt;&amp;lt; in; &lt;br /&gt;
	// prin shiftare&lt;br /&gt;
	// 1&amp;lt;&amp;lt;0 == 1 == 4&amp;#039;b0001; &lt;br /&gt;
	// 1&amp;lt;&amp;lt;1 == 2 == 4&amp;#039;b0010; &lt;br /&gt;
	// 1&amp;lt;&amp;lt;2 == 4 == 4&amp;#039;b0100; &lt;br /&gt;
	// 1&amp;lt;&amp;lt;3 == 8 == 4&amp;#039;b1000; &lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului top  (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
// observatie: &lt;br /&gt;
	// puteti da in vivado: rtl analysis -&amp;gt; open elaborated design -&amp;gt; schematic pentru a vedea desenul rezultat&lt;br /&gt;
	// puteti vedea ca moduri diferite de scriere produc aparitia a diferite primitive de sinteza&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out_v1, // fiecare varianta de decodor cu iesirea lui&lt;br /&gt;
		output logic [3:0] out_v2, // toate ar trebui sa scoata acelasi rezultat &lt;br /&gt;
		output logic [3:0] out_v3,&lt;br /&gt;
		output logic [3:0] out_v4,&lt;br /&gt;
		output logic [3:0] out_v5,&lt;br /&gt;
		output logic [3:0] out_v6&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v1 decodor_v1_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
decodor_v2 decodor_v2_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v2)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v3 decodor_v3_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v3)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v4 decodor_v4_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v4)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v5 decodor_v5_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v5)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
decodor_v6 decodor_v6_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v6)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
===Exercitiul 1: Multiplexorul===&lt;br /&gt;
&lt;br /&gt;
Multiplexorul (mux) este un circuit ce are rolul de a selecta una dintre intrari pentru ca aceasta sa ajunga la iesire.&lt;br /&gt;
&lt;br /&gt;
Imaginati-va o intersectie in care toate masinile vor sa se iasa catre aceasi strada. Pentru a evita accidente, este nevoie de un element de control, de selectie, prin care se hotaraste care dintre intrari este lasata sa ajunga la iesire, in respectivul moment de timp.&lt;br /&gt;
Multiplexorul poate fi de asemenea vazut ca un comutator.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 1:&amp;#039;&amp;#039;&amp;#039; conceptul de baza al multiplexarii este absolut vital si o sa apara des in multe zone ale ingineriei si la materii foarte diferite. &lt;br /&gt;
Ca niste mici exemple, el se foloseste in:&lt;br /&gt;
:a) telecomunicatii - cine are voie sa comunice pe un fir la un moment de timp &lt;br /&gt;
:b) internet - routere - cine trimite pachetele tcp/ip catre destinatia x&lt;br /&gt;
:c) panouri cu leduri - aprindere pe rand a ledurilor (de la instalatii de craciun pana la ecrane/televizoare care aprind randurile alternativ)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 2:&amp;#039;&amp;#039;&amp;#039; numarul de intrari maxim posibile este 2^(nr_biti_selectie)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 3:&amp;#039;&amp;#039;&amp;#039; multiplexoarele pot avea intrarile date si iesirea pe mai multi biti.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 4:&amp;#039;&amp;#039;&amp;#039; este de ajutor sa incepeti sa vedeti circuitele ca avand o cale de date ce sunt procesate si o cale de control care decide cum se face asta.&lt;br /&gt;
Aici calea de date este alcatuita din intrari si iesire, iar calea de control din firele de selectie. &lt;br /&gt;
Acest principiu se propaga si in arhitectura microprocesoarelor unde vor aparea magistrale si memorii de date/instructiuni.&lt;br /&gt;
&lt;br /&gt;
Pornind de la exemplul oferit, implementati multiplexorul in cat mai multe variante.&lt;br /&gt;
&lt;br /&gt;
Multiplexorul cu 2 intrari pe un bit fiecare (mux elementar) este desenat in figurile de mai jos: cum este vazut din exterior (prima figura) si alcatuirea lui interna (a doua figura). &lt;br /&gt;
&lt;br /&gt;
[[Fișier:mux2_general.png ‎| 300px]]&lt;br /&gt;
[[Fișier:mux2_schema_interna.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 10ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_mux2.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: Implementati un mux4 (multiplexor cu 4 intrari)===&lt;br /&gt;
&lt;br /&gt;
Interfata lui este ca in figura de mai jos. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:mux_general.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Pentru varianta lui structurala, mux4 se construieste din mai multe mux2 legate corespunzator. Incercati sa construiti voi aceasta schema.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 10ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_mux4.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Demultiplexorul===&lt;br /&gt;
&lt;br /&gt;
Demultiplexorul (demux) este un circuit ce are rolul de a selecta catre care iesire se va duce intrarea. &lt;br /&gt;
Imaginati-va o intersectie in care intra o singura masina si trebuie sa decida daca iese catre stanga/inainte/dreapta. 	&lt;br /&gt;
&lt;br /&gt;
Pentru acest exercitiu se va implementa un demux2 (cu 2 iesiri).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 1&amp;#039;&amp;#039;&amp;#039;: celelalte iesiri, cele neselectate iau valoarea 0.&lt;br /&gt;
	&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 2&amp;#039;&amp;#039;&amp;#039;: numarul de iesiri maxim posibile este 2^(nr_biti_selectie)&lt;br /&gt;
&lt;br /&gt;
Interfata demultiplexorului este data mai jos. Incercati sa construiti acest circuit in cat mai multe variante de sintaxa posibile (minim 4).	&lt;br /&gt;
&lt;br /&gt;
[[Fișier:demux2_general.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda pentru a vedea functionarea demultiplexorului.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Sumatorul===&lt;br /&gt;
&lt;br /&gt;
Sumatorul are rolul de a scoate la iesire suma celor 2 intrari.&lt;br /&gt;
&lt;br /&gt;
Uzual el mai are si intrare si iesire de &amp;quot;carry&amp;quot; adica de transport (cand se depaseste baza de numarare si e nevoie de inca o cifra, ex in zecimal: 88 + 20 = 108; apare o cifra in plus, cifra sutelor). &lt;br /&gt;
&lt;br /&gt;
[[Fișier:sumator_8b_general.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Observatie: desi scrierea cu assign si + este cea mai usoara si clara pentru un sumator, si celelalte moduri de scriere sunt posibile.&lt;br /&gt;
La aceasta scriere, daca se doresta ca sumatorul sa aiba carry out, sumatorul se poate face cu un bit mai mare decat intrarile, iar acel bit sa fie conectat la carry out. Practic, obtii un rezultat pe &amp;quot;n&amp;quot; biti + un bit de depasire, anume msb-ul. &lt;br /&gt;
&lt;br /&gt;
Generati formele de unda necesare testarii sumatorului pe 8b.&lt;br /&gt;
&lt;br /&gt;
Pentru a vedea pas cu pas cum se construieste un sumator pe 8b puteti parcurge urmatoarea platforma de laborator: [https://wiki.dcae.pub.ro/images/0/0f/Cid_gan_sumator_aplicatia_2.pdf Sumator.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Comparatorul===&lt;br /&gt;
&lt;br /&gt;
Comparatorul are rolul de a vedea relatia dintre cele 2 intrari ale sale, daca cele 2 numere sunt egale, daca primul e mai mic sau mai mare. &lt;br /&gt;
&lt;br /&gt;
Astfel el poate avea 3 iesiri dintre care se activeaza doar una: &lt;br /&gt;
:- iesire de egalitate&lt;br /&gt;
:- iesire de in0 &amp;lt; in1 &lt;br /&gt;
:- iesire de in0 &amp;gt; in1 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
Se mai poate face si o varianta de comparator cu 2 iesiri, asa cum veti studia la arhitectura microprocesoarelor.&lt;br /&gt;
:- iesire de egalitate&lt;br /&gt;
:- iesire care este 0 daca in0&amp;lt;in1 sau 1 daca in0&amp;gt;in1&lt;br /&gt;
&lt;br /&gt;
Aceasta abordare este folosita la AMP la flag-urile din procesoare, folosind operatia de scadere si flag-urile de &amp;quot;zero&amp;quot; si &amp;quot;negativ&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Scrieti modulul de comparator, in ambele variante de interfata. Intrarile pot avea oricat de multi biti (comparator mai mic sau mai mare), pentru acest exercitiu sa il faceti pe 4b.&lt;br /&gt;
&lt;br /&gt;
Scrieti un testbench care sa genereze toate combinatiile posibile de date de la intrare. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Discutie&amp;#039;&amp;#039;&amp;#039;: Daca acest comparator are datele pe 32b sau mai mult (sau daca circuitul devine mult mai complex), nu se mai poate face o astfel de testare exhaustiva a combinatiilor posibile de date de la intrare pentru ca simularea ar dura prea mult. De situatia asta se ocupa inginerii de verificare ce lucreaza in paralel cu inginerii de design. Pentru mai multe detalii puteti cauta &amp;quot;constrained random functional verification&amp;quot;. Incercati sa identificati cazurile/situatiile ce ar trebui testate pentru un comparator pe 32b inainte de a spune ca acesta functioneaza corect (minim 10).&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=7939</id>
		<title>CID aplicatii 2 : Instantiere si porti logice</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=7939"/>
		<updated>2025-03-04T09:38:58Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exercitiul 5: AND4 pe 4b din AND4 pe 1b */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie: incapsulare si instantiere==&lt;br /&gt;
Unitatile constructive de baza din care se formeaza circuitele digitale se numesc porti logice. Acestea implementeaza functii logice si prin conectarea mai multor astfel de circuite simple complexitatea unui circuit poate creste pana la nivelul procesoarelor actuale. Pentru a putea controla cresterea complexitatii in proiectarea unui circuit de dimensiuni mari se folosesc 2 concepte cheie: &lt;br /&gt;
&lt;br /&gt;
1) incapsularea functiei dorite intr-un modul&lt;br /&gt;
&lt;br /&gt;
2) instantierea unor module mai mici si asamblarea acestora pentru a forma un modul mai mare. &lt;br /&gt;
&lt;br /&gt;
Incapsularea se refera la a grupa elementele ce alcatuiesc o anumita functionalitate intr-un modul. Aceste elemente pot la randul lor sa fie alte module.&lt;br /&gt;
Instantierea (asemanator cu POO) se refera la a apela un modul deja scris pentru a fi folosit efectiv in circuitul curent. &lt;br /&gt;
Pentru a face o analogie cu programarea, cand se declara o variabila (sau un obiect), tipul variabilei este echivalent cu modulul si numele ei este numele instantei.&lt;br /&gt;
&lt;br /&gt;
Pentru a intelege aceste concepte se da circuitul de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_instantiere.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1) Notatie aici: Numele modulului este scris in interior. &lt;br /&gt;
&lt;br /&gt;
2) Notatie aici: Numele instantei este scris deasupra.&lt;br /&gt;
&lt;br /&gt;
3) Idee fundamentala: prin instantierea si incapsularea unor circuite simple, mici, apar circuite mai complexe.&lt;br /&gt;
&lt;br /&gt;
4) Idei esentiale (daca vreuna e neclara consultati cadrul didactic): &lt;br /&gt;
&lt;br /&gt;
:a) &amp;quot;modul_2&amp;quot; este instantiat o singura data in tot proiecul, iar instanta se cheama &amp;quot;x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:b) &amp;quot;modul_2&amp;quot; are o intrare numita &amp;quot;in0&amp;quot; si o iesire numita &amp;quot;out0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:c) &amp;quot;modul_2&amp;quot; este instantiat in cadrul &amp;quot;modul_6&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:d) Modulul cel mai mare, ce cuprinde toata functionalitatea dorita a sistemului (aici &amp;quot;modul_6&amp;quot;) se numeste uzual top.&lt;br /&gt;
&lt;br /&gt;
:e) Instanta top-ului care apare atunci cand se doreste testarea sa in simulare intr-un testbench (tb) se numeste uzual DUT (design under test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:f) &amp;quot;modul_0&amp;quot; apare instantiat de 3 ori. Circuitul final, cuprinde 3 subcircuite de tip &amp;quot;modul_0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:g) La nivel de top, instanta sa se cheama &amp;quot;b&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
:h) La nivel de &amp;quot;modul_5&amp;quot;, cele 2 instante se cheama &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:i) &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot; sunt 2 circuite fizice diferite chiar daca ambele sunt de tipul &amp;quot;modul_0&amp;quot;. Fiind instante ale aceluiasi modul, deci identice in alcatuire, luate separat ele fac acelasi lucru. Luate in contextul lui &amp;quot;modul_5&amp;quot;, &amp;quot;a&amp;quot; genereaza datele de pe firul &amp;quot;w0&amp;quot; si &amp;quot;c&amp;quot; genereaza datele pentru iesire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:j) circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_1&amp;quot; (instantiat in &amp;quot;modul_5&amp;quot;) este complet diferit de circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_0&amp;quot; (instantiat in top). Este permis ca ele sa aiba acelasi nume (cele 2 instante) deoarece se afla in locatii diferite. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:k) Identic, mai multe module au o intrare numita &amp;quot;in_0&amp;quot;. La sinteza circuitului nu se face confuzie intre acestea deoarece fiecare e vazut la nivelul altei instante.&lt;br /&gt;
&lt;br /&gt;
:l) Identic, firele de legatura &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:m) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w2&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;b&amp;quot; la intrarea &amp;quot;in2&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:n) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;x&amp;quot; la intrarea &amp;quot;in1&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:o) La nivelul &amp;quot;modul_5&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea instantei &amp;quot;b&amp;quot; la intrarea instantei &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:Pentru claritatea desenului, respectivele intrari si iesiri nu au fost denumite. In cod este obligatoriu ca ele sa fie definite si denumite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:p) La nivelul &amp;quot;top&amp;quot;, &amp;quot;in0&amp;quot;,&amp;quot;in1&amp;quot;,&amp;quot;in2&amp;quot;,&amp;quot;in3&amp;quot;,&amp;quot;in4&amp;quot; si &amp;quot;out0&amp;quot; formeaza interfata modulului (semnalele care intra sau ies din modul).&lt;br /&gt;
&lt;br /&gt;
:q) La nivelul &amp;quot;top&amp;quot;, &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;, &amp;quot;w2&amp;quot; sunt fire interne de legatura.&lt;br /&gt;
&lt;br /&gt;
:r) La nivelul &amp;quot;top&amp;quot;, firul &amp;quot;in3&amp;quot; este conectat ca intrare pentru 3 submodule.&lt;br /&gt;
&lt;br /&gt;
==Teorie: testarea circuitelor==&lt;br /&gt;
Pentru a se testa functionarea corecta a circuitului final, acesta este instantiat intr-un modul numit &amp;quot;test_bench&amp;quot; sau &amp;quot;tb&amp;quot;. Acest modul este folosit strict in simulare. &lt;br /&gt;
Testarea unui circuit are loc conform schemei urmatoare: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_tb.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Generarea datelor de intrare se va face asemanator cu laboratorul 1.&lt;br /&gt;
&lt;br /&gt;
Voi veti avea rolul modelului ideal si al comparatorului datelor de iesire, uitandu-va la datele de intrare veti calcula iesirea corecta si apoi veti compara aceasta valoare cu raspunsul circuitului ce se testeaza.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In cazul unui sistem automat, se genereaza mesaje de eroare sau mesaje ca functionarea este in regula.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Observatie: proiectarea si verificarea sunt 2 domenii diferite, firmele avand departamente separate pentru acestea. &lt;br /&gt;
&lt;br /&gt;
Proiectarea/Design se ocupa cu scrierea in Verilog/SystemVerilog a modului de top si toate modulele ce se afla in acesta, avand ca scop final realizarea fizica pe placa a unui circuit. &lt;br /&gt;
&lt;br /&gt;
Verificarea se ocupa de scrierea in SystemVerilog (limbaj format din Verilog cu concepte de POO) a modului de testbench si generarea de stimuli si scenarii care sa testeze functionarea design-ului.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: porti logice==&lt;br /&gt;
Portile logice folosite uzual, impreuna cu tabelele lor de adevar si reprezentarea grafica sunt date mai jos.&lt;br /&gt;
&lt;br /&gt;
Se folosesc porti logice cu 1 sau 2 intrari, cele cu mai mult de 2 intrari fiind construite din acestea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tip !! Simbol !! Tabel de adevăr !! Tip !! Simbol !! Tabel de adevăr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Buffer/Repetor&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:Buffer_gate.png|Buffer symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOT&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:not.png|NOT symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || NOT A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;AND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:and.png|AND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A AND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NAND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nand.png|NAND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NAND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;OR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:or.png|OR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A OR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nor.png|NOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xor.png|XOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XNOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xnor.png|XNOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XNOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Despre FPGA==&lt;br /&gt;
FPGA-ul (Field-Programmable Gate Array) este un circuit programabil, capabil sa implementeze circuite definit de utilizator. El este format dintr-o matrice de blocuri programabile, interconectate intre ele printr-o serie de conexiuni la randul lor programabile.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cand se doreste implementarea unui circuit pe FPGA, acesta urmeaza urmatoarele etape: &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Elaborarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care codul SystemVerilog este transformat intr-un circuit la nivel de porti si registre (netlist) si este independent de modelul de FPGA folosit. &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Sinteza&amp;#039;&amp;#039;&amp;#039; este procesul în care se realizează transformarea circuitului descris într-un netlist dependent de tehnologie. Se vor folosi la acest pas primitivele disponibile pe FPGA.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Implementarea&amp;#039;&amp;#039;&amp;#039; este procesul în care se preia netlist-ul ce conține primitivele FPGA și modul lor de interconectare realizat la pasul de sinteză și se realizează maparea lor efectivă în FPGA (place and route).&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Generarea Bitstream-ului&amp;#039;&amp;#039;&amp;#039; este procesul prin care informatiile din implementare sunt asamblate intr-un singur fisier.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Programarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care fisierul generat anterior este trimis efectiv catre placa cu FPGA (prin USB) unde determina modificarea valorilor si conexiunilor interne din aceasta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O introducere mai detaliata poate fi gasita aici : [[FPGA - Introducere]].&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Fpgaimg.PNG|600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Pentru a putea controla circuitul propus si a putea vedea rezultatele, intrarile si iesirile (input si output din module) in/din acesta trebuie conectate la pini fizici ai FPGA-ului care sunt conectati la butoane/switch-uri/leduri.&lt;br /&gt;
* Conexiunile dintre butoane/switch-uri si pinii FPGA sunt fixe. La fel si cele intre pinii FPGA si LED-uri. (in functie de PCB)&lt;br /&gt;
* Conexiunile dintre porturile modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; si pinii FPGA sunt configurabile. (in functie de noi, prin fisierul XDC)&lt;br /&gt;
* Legarea porturilor modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; la pinii fizici ai FPGA se realizeaza prin configurarea conexiunilor din FPGA conform contrangerilor de I/O pe care le vom mentiona in proiect, inainte de sinteza.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 1: Analiza circuitelor cu porti===&lt;br /&gt;
Fie urmatorul circuit alcatuit din porti logice:&lt;br /&gt;
 [[Fișier:Mux2_schema_interna_2.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Se doreste exprimarea circuitului de mai sus ca formula de tip: iesire = f(intrari). &lt;br /&gt;
&lt;br /&gt;
Pentru asta, abordarea consta in a porni de la iesire si a merge pas cu pas catre intrari, asa cum este exemplificat mai jos. Se vor folosi simbolurile &amp;quot;~&amp;quot; pentru NOT, &amp;quot;&amp;amp;&amp;quot; pentru AND, &amp;quot;|&amp;quot; pentru OR.&lt;br /&gt;
:pas1: out0 = ?&lt;br /&gt;
:pas2: out0 = w1 | w2&lt;br /&gt;
:pas3: out0 = w1 | ( ? )&lt;br /&gt;
:pas4: out0 = w1 | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas5: out0 = ( ? ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas6: out0 = ( in0 &amp;amp; w0 ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas7: out0 = ( in0 &amp;amp; ( ? ) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas8: out0 = ( in0 &amp;amp; (~sel) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: NAND2 din AND2 si NOT===&lt;br /&gt;
In urmatorul exemplu se implementeaza o poarta NAND din o poarta AND si o poarta NOT. &lt;br /&gt;
&lt;br /&gt;
Codul de mai jos exemplifica ideea de instantiere si contine comentarii legate de sintaxa SystemVerilog necesara.&lt;br /&gt;
&lt;br /&gt;
In mod uzual fisierele sunt denumite dupa modulul ce se afla in ele, in fiecare fisier fiind un singur modul.&lt;br /&gt;
&lt;br /&gt;
Schema circuitul care se doreste a fi creat este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_exemplu_rezolvat.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii NOT (fisierul not_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
// comentarii cu &amp;quot;//&amp;quot; sau cu /* .... */ ;&lt;br /&gt;
/* &lt;br /&gt;
	ca in c/c++ &lt;br /&gt;
*/ &lt;br /&gt;
&lt;br /&gt;
module not_gate	// cuvant cheie &amp;quot;module&amp;quot; apoi numele modulului (asemanator clase din c++)&lt;br /&gt;
	( // intre paranteze se pune interfata (firele care intra sau ies din modul)&lt;br /&gt;
		input logic in0,         // in0 este o intrare =&amp;gt; input&lt;br /&gt;
		output logic out0	// out0 este o intrare =&amp;gt; output&lt;br /&gt;
	); // aici &amp;quot;;&amp;quot; sa nu il uitati&lt;br /&gt;
&lt;br /&gt;
assign out0 = ~in0;	// cuvant cheie assign; &lt;br /&gt;
					// semnalele pot lua valoare prin assign&lt;br /&gt;
					// ~ e semnul pentru negatie pe biti (ca in c/c++)&lt;br /&gt;
&lt;br /&gt;
endmodule // cuvant cheie &amp;quot;endmodule&amp;quot;. orice module se inchide cu endmodule.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii AND (fisierul and_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and_gate&lt;br /&gt;
	(&lt;br /&gt;
		input logic in0,	// aici sunt 2 intrari &lt;br /&gt;
		input logic in1,	&lt;br /&gt;
		output logic out0&lt;br /&gt;
	); // nu conteaza ordinea in care sunt puse intrarile si iesirile.&lt;br /&gt;
			// uzual si pentru usurinta se ordoneaza si grupeaza dupa functionalitate&lt;br /&gt;
			// in cazul de mai sus, am pus intai intrarile, apoi iesirile.&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 &amp;amp; in1; // operatia propriu zisa &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului top (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic a,&lt;br /&gt;
		input logic b,&lt;br /&gt;
		output logic c&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic w0;    //declarat un fir intern de legatura &lt;br /&gt;
    &lt;br /&gt;
and_gate and_gate_0	// instantiere: nume_modul nume_instanta (asemanator int x din c/c++)&lt;br /&gt;
	(&lt;br /&gt;
		.in0(a), // la intrarea &amp;quot;in0&amp;quot; a instantei &amp;quot;and_gate_0&amp;quot;  se conecteaza firul &amp;quot;a&amp;quot; din top&lt;br /&gt;
		.in1(b), // grija ca &amp;quot;in0&amp;quot;, &amp;quot;in1&amp;quot;, &amp;quot;out0&amp;quot; sa existe in declararea modulului &amp;quot;and_gate&amp;quot;&lt;br /&gt;
		.out0(w0) // grija ca &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;w0&amp;quot; sa existe la nivelul modulului in care se face instantierea&lt;br /&gt;
	);    &lt;br /&gt;
    &lt;br /&gt;
not_gate not_gate_0&lt;br /&gt;
	(&lt;br /&gt;
		.in0(w0), // &amp;quot;w0&amp;quot; care iese din &amp;quot;and_gate_0&amp;quot; intra in &amp;quot;not_gate_0&amp;quot;&lt;br /&gt;
		.out0(c) // &amp;quot;c&amp;quot; care iese din &amp;quot;not_gate_0&amp;quot; iese din modulul &amp;quot;top&amp;quot; (e iesire in interfata de sus)&lt;br /&gt;
	);   // se poate scrie si &amp;quot;.in0(w0),.out0(c)&amp;quot; dar se prefera fiecare fir pe randul sau (lizibilitate si loc de comentarii pt design-uri complexe)&lt;br /&gt;
	// Observatie: la varianta de mai sus de instantiere, nu conteaza ordinea firelor. &lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
not_gate not_gate_0		&lt;br /&gt;
	(				// se poate instantia si in forma prescurtata ca aici &lt;br /&gt;
		w0,				// in acest caz se pun conexiunile in ordinea in care sunt declarate intrarile si iesirile din modul&lt;br /&gt;
		c	// NU se recomanda stilul asta de instantiere&lt;br /&gt;
	); 			// apar greseli frecvent la ordinea firelor si la numarul lor, &lt;br /&gt;
*/				// mai ales daca modulul e complex si are multe intrari si intrari&lt;br /&gt;
 &lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Echivalent se pot folosi si &amp;quot;primitive&amp;quot; SystemVerilog pentru scrierea top-ului.&lt;br /&gt;
&lt;br /&gt;
Primitivele sunt circuite care exista deja in limbaj, folosite atunci cand se doreste o descriere structurala a circuitului.&lt;br /&gt;
&lt;br /&gt;
In instantiere acestora, iesirea se pune prima, urmata de intrari.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; daca se doreste scrierea acestor porti de catre voi (ca mai sus), numele modulului nu trebuie sa fie un cuvant cheie ocupat de primitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v2&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
  &lt;br /&gt;
logic w0;&lt;br /&gt;
&lt;br /&gt;
and and_gate_0(w0,a,b);	// primitiva pentru poarta and&lt;br /&gt;
not not_gate_0(c,w0);  	// primitiva pentru poarta not&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fiind un modul simplu, intreaga functionalitate putea fi scrisa la nivel de &amp;quot;top&amp;quot; si simplificat ca mai jos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v3.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v3&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
   &lt;br /&gt;
assign c = ~ (a &amp;amp; b); // a si b, negate&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Testarea circuitul se face printr-un testbench, acesta fiind:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea testbench-ului (fisierul top_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module top_tb(); // din/in tb nu intra si iese nimic. niciodata.&lt;br /&gt;
&lt;br /&gt;
logic a_tb;	&lt;br /&gt;
logic b_tb;	&lt;br /&gt;
logic c_tb;	&lt;br /&gt;
&lt;br /&gt;
top dut	// instantierea modulului de tip &amp;quot;top&amp;quot; sub numele &amp;quot;dut&amp;quot; &lt;br /&gt;
	(&lt;br /&gt;
		.a(a_tb),&lt;br /&gt;
		.b(b_tb),&lt;br /&gt;
		.c(c_tb)&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin // in loc de { ... } din c/c++, in SystemVerilog se pune begin ... end &lt;br /&gt;
	#10;		// dupa 10 unitati de timp &lt;br /&gt;
	a_tb = 0;		// a_tb ia valoarea 0&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;		// dupa inca 10 unitati de timp, deci in total la 20&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	&lt;br /&gt;
	#20 $stop();	// oprirea simularii &lt;br /&gt;
end //end pentru initial &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formele de unda rezultate din simulare se pot vedea mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:exemplu_rezolvat_nand_forme_de_unda.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In chenarul verde se pot observa instantele din simulare. &lt;br /&gt;
&lt;br /&gt;
Daca se doreste adaugarea de semnale noi pentru a fi vazute, se selecteaza modulul instantiat in care acestea se afla (chenar verde). &lt;br /&gt;
&lt;br /&gt;
Apoi, din chenarul rosu se aleg semnalele si se adauga prin click dreapta-&amp;gt;add to wave window. &lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara vizualizare, semnalele se pot grupa asa cum se vede in chenarul mov prin click dreapta-&amp;gt;new group.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se observa o functionare corecta circuitului, acesta fiind o poarta NAND. El scoate &amp;quot;0&amp;quot; cand ambele semnale de intrare sunt &amp;quot;1&amp;quot; si scoate &amp;quot;1&amp;quot; in rest.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea circuitului pe FPGA&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dupa ce circuitul a fost testat in simulare, se doreste punerea sa fizica pe placa FPGA. Pentru aceasta, se tine cont de urmatoarele.&lt;br /&gt;
&lt;br /&gt;
* Pentru a controla intrarile &amp;#039;&amp;#039;a&amp;#039;&amp;#039; si &amp;#039;&amp;#039;b&amp;#039;&amp;#039; ale circuitului &amp;#039;&amp;#039;&amp;#039;top&amp;#039;&amp;#039;, va trebui sa le conectam prin intermediul conexiunilor configurabile ale FPGA-ului la pini ce sunt mai departe conectati fizic la dispozitive ce pot controla valorile semnalelor (switch-uri, butoane).&lt;br /&gt;
* Pentru a observa valoarea iesirii, vom conecta semnalul de iesire &amp;#039;&amp;#039;c&amp;#039;&amp;#039;la un dispozitiv de observare, cum ar fi un LED, care va fi aprins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 1 si stins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 0.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:NAND2 FPGA.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru a realiza conectarea porturilor modulului &amp;#039;&amp;#039;top&amp;#039;&amp;#039; la pinii fizici ai FPGA ce sunt conectati mai departe la componentele de pe placa, va trebui sa specificam in utilitarul de sinteza maparea porturilor la acestia. Maparea se realizeaza prin mentionarea codurilor pinilor la care dorim conexiunea si poata numele de &amp;#039;&amp;#039;&amp;#039;constrangeri de I/O&amp;#039;&amp;#039;&amp;#039;. Aceste coduri sunt mentionate in documentatia placii de dezvoltare cu FPGA (in cazul nostru, Boolean Board) si pot fi regasite si in pagina [[Boolean Board - Pinout]].&lt;br /&gt;
&lt;br /&gt;
Conform schemei, la acest exemplu avem nevoie de codurile pinilor conectati mai departe la Switch0, Switch1 si LED0.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Daca intrarile si iesirile ar fi semnale pe mai multi biti, fiecare bit al intrarilor va fi conectat la cate un switch/buton si fiecare bit al iesirii va fi conectat la un LED. Acest lucru este necesar deoarece switch-urile/butoanele pot avea doar doua stari (0 si 1) si astfel pot controla un singur bit. La fel, un LED poate avea doar doua stari (0 - stins si 1 - aprins) si poate afisa starea unui singur bit.&lt;br /&gt;
&lt;br /&gt;
Dupa ce ati extras codurile necesare, urmati pasii descrisi in [[Tutorial_Vivado|tutorialul Vivado]]. &lt;br /&gt;
&lt;br /&gt;
Dupa programarea cu succes a placii, puteti testa functionalitatea circuitului prin modficarea valorilor switch-urilor si observarea starii LED-ului.&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
Pentru urmatoarele exercitii se doreste atat testarea designurilor prin simulare cat si punerea acestora pe placa. Legat de placa, intrarile vor fi conectate la butoane, iar iesirile la leduri. Se va consulta tabelul cu pini disponibili ([[Boolean Board - Pinout]].).&lt;br /&gt;
&lt;br /&gt;
Exista moduri mai rapide de a scrie functionalitatea dorita (vezi exemplu), dar tema principala a acestui laborator este instantierea, asa ca sunteti rugati sa respectati desenele si sa instantiati fiecare poarta individual.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: AND4 din AND2=== &lt;br /&gt;
&lt;br /&gt;
Acest exercitiu arata cum se construieste o poarta AND cu 4 intrari din porti AND mai simple, cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca toate intrarile sunt &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_and4.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: OR4 din OR2===&lt;br /&gt;
&lt;br /&gt;
Asemanator cu exercitiul anterior, se poate construi si o poarta or cu 4 intrari din porti or cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca oricare din intrari (cel putin una) este &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_or4_din_or2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: AND4 din AND2 aranjat in cascada (nu arbore)===&lt;br /&gt;
&lt;br /&gt;
In multe cazuri, aceeasi functionalitate poate fi atinsa prin circuite care arata diferit. &lt;br /&gt;
O alta varianta de a face o poarta AND cu 4 intrari este prezentata mai jos. &lt;br /&gt;
&lt;br /&gt;
Comparati cele 2 variante. &lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2_v2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: AND4 din NAND2===&lt;br /&gt;
&lt;br /&gt;
Orice poarta logica de baza poate fi construita doar din porti NAND sau doar din porti NOR. &lt;br /&gt;
&lt;br /&gt;
Desenati si implementati circuitul pentru o poarta AND4 din porti NAND cu 2 intrari. &lt;br /&gt;
&lt;br /&gt;
Tip: Incercati intai sa generati o poarta AND2 din NAND2.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: AND4 pe 4b din AND4 pe 1b===&lt;br /&gt;
&lt;br /&gt;
Se pot face operatii logice si pe mai multi biti deodata prin punerea in paralel a mai multor porti cu o singura iesire.&lt;br /&gt;
	Exemplu :&lt;br /&gt;
		pentru intrarile 0011 si 1110 iesirea va fi 0010&lt;br /&gt;
&lt;br /&gt;
Pentru exersarea instantierii si intelegerea circuitului din spatele operatilor multibit implementati acest circuit prin instantierea a 4 porti AND4 pe 1 bit intr-o poarta AND4 pe 4 biti.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v1.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns):&lt;br /&gt;
 &lt;br /&gt;
[[Fișier:Wavedrom_and4_4b.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
Exista si un mod mai rapid si simplu de a scrie aceasta functionalitate, grupand intrarile si iesirile in &amp;quot;bus&amp;quot;-uri, ca in codul de mai jos.&lt;br /&gt;
Acest mod de a grupa firele este desenat mai jos.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Fisierul and4_4b.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and4_4b&lt;br /&gt;
	(&lt;br /&gt;
		input logic [3:0] in0,	// in0 are 4b, de la bit 3 la bit 0 inclusiv &lt;br /&gt;
		input logic [3:0] in1,	// se noteaza msb:lsb (most significant bit: least significant bit) (echivalent cu conceptul de cifra sutelor, cifra unitatilor, pt binar)&lt;br /&gt;
		input logic [3:0] in2,&lt;br /&gt;
		input logic [3:0] in3,&lt;br /&gt;
		output logic [3:0] out0&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
assign out0 = in0 &amp;amp; in1 &amp;amp; in2 &amp;amp; in3;&lt;br /&gt;
	&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Desenati schemele logice pentru urmatoarele circuite:===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;a) Schema 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema1 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f, g;&lt;br /&gt;
	&lt;br /&gt;
	logic w1;&lt;br /&gt;
	logic w2;&lt;br /&gt;
	&lt;br /&gt;
	and P1 ( w1, a, c );&lt;br /&gt;
	or P2 ( f, w1, w2, d);&lt;br /&gt;
	not P3 (w2, b);&lt;br /&gt;
	and P4 (g, w1, b, d);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observatie: In versiunea veche de verilog (si s-a pastrat si in cea curenta), se pot specifica directiile porturilor si in exteriorul parantezelor, ca mai sus. &lt;br /&gt;
Aceasta scriere NU este recomandata. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;b) Schema 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema2 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f;&lt;br /&gt;
	&lt;br /&gt;
	logic w1, w2;&lt;br /&gt;
	&lt;br /&gt;
	nand P1 ( w1, a, b ), P2 (w2, c, d);&lt;br /&gt;
	and P3 ( f, w1, w2);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; asemanator cu C/C++, se pot face declaratii in aceeasi linie a mai multor &amp;quot;variabile&amp;quot;, aici fire sau instante, cum se poate vedea la w1 si w2 (ambele fiind fire) sau la P1 si P2 (ambele fiind porti nand).&lt;br /&gt;
Aceasta scriere NU este recomandata.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_3_:_Circuite_combinationale_elementare&amp;diff=7938</id>
		<title>CID aplicatii 3 : Circuite combinationale elementare</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_3_:_Circuite_combinationale_elementare&amp;diff=7938"/>
		<updated>2025-03-04T09:36:14Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exercitiul 3: Demultiplexorul */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Teorie==&lt;br /&gt;
Acest laborator are ca scop scrierea unor circuite combinationale simple si explorarea variantelor de sintaxa diferite ce ajung sa ofere aceeasi functionalitate. Sintaxa va fi explicata in comentariile exemplului rezolvat mai jos.&lt;br /&gt;
&lt;br /&gt;
Descrierea circuitelor in SystemVerilog se face in una din doua forme:&lt;br /&gt;
&lt;br /&gt;
:1) structurala - descrie cum un modul e alcatuit din module sau primitive mai simple&lt;br /&gt;
&lt;br /&gt;
:2) comportamentala/behavioural - descrie cum se calculeaza iesirile din intrari&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exemplu - Decodorul==&lt;br /&gt;
Decodorul este un circuit a carui iesire pe n biti are un singur bit de &amp;quot;1&amp;quot;, anume cel selectat prin singura sa intrare pe log2(n) biti. &lt;br /&gt;
Astfel, pentru un decodor cu iesire pe 8b, intrarea va avea 3b (logaritm in baza 2 din 8) si tabelul de adevar va arata astfel: &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| in(3b) || out(8b) &lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|000 || 0000_0001&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|001 || 0000_0010&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|010 || 0000_0100&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|011 || 0000_1000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|100 || 0001_0000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|101 || 0010_0000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|110 || 0100_0000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|111 || 1000_0000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Iesirea este numerotata de la bitul 7 (msb) pana la bitul 0 (lsb). Se observa ca daca intrarea are valoare &amp;quot;a&amp;quot;, singurul bit de &amp;quot;1&amp;quot; din iesire este cel de pe pozitia &amp;quot;a&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Atat in tabelul de mai sus, cat si in codul SystemVerilog poate sa apara &amp;quot;_&amp;quot; (underscore) ca sa ajute vizual la separarea/numararea cifrelor. Se foloseste in mod uzual la scrierea in binar ca sa grupeze 4b (o cifra in hexa).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Circuitul exemplu al acestui laborator va fi un decodor mai mic, cu 2 biti de intrare si 4 de iesire, avand tabelul de adevar:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| in(2b) || out(4b) &lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|00 || 0001&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|01 || 0010&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|10 || 0100&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|11 || 1000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
O varianta de schema care implementeaza acest circuit este cea de mai jos: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:w3_exemplu_rezolvat.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
In circuitul de mai sus, apare dubla negatie, respectivul semnal putand fi luat si direct de la intrare. Acest lucru se intampla din considerente electrice. Desi pe desene nu sunt trecute, fiecare poarta are si fire de alimentare si de masa. Astfel, pentru a evita fire de lungimi foarte mari sau fire care se propaga in multe intrari si probleme de cadere a tensiunilor, se folosesc astfel de buffere/repetoare. &lt;br /&gt;
&lt;br /&gt;
Codul de mai jos exemplifica moduri diferite de a exprima aceasta functionalitate.&lt;br /&gt;
El contine comentarii referitoare la sintaxa de baza SystemVerilog, necesara implementarii modulelor in diverse moduri. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor - varianta structurala din porti, cu primitive (fisierul decodor_v1.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v1&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,	// definirea intrarilor sub forma de &amp;quot;bus&amp;quot; &lt;br /&gt;
									// bus-ul de intrare se numeste &amp;quot;in&amp;quot; si este pe 2 biti: in[1], in[0]&lt;br /&gt;
									// fizic sunt 2 fire distincte, grupate pentru o mai simpla folosire.&lt;br /&gt;
		output logic [3:0] out 	// avem o iesire, numita &amp;quot;out&amp;quot; pe 4 biti.&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
logic in_0_inv;&lt;br /&gt;
logic in_1_inv;&lt;br /&gt;
logic in_0_nat;&lt;br /&gt;
logic in_1_nat;&lt;br /&gt;
&lt;br /&gt;
not not_gate_0(in_0_inv,in[0]); // aleg bitul 0 al lui in sa intre in aceasta poarta not;&lt;br /&gt;
&lt;br /&gt;
not not_gate_1(in_1_inv,in[1]); // observatie: cele 2 fire si cele 2 porti putea fi comprimate intr-un bus + poarta not pe 2 biti.&lt;br /&gt;
&lt;br /&gt;
not not_gate_2(in_0_nat,in_0_inv);&lt;br /&gt;
&lt;br /&gt;
not not_gate_3(in_1_nat,in_1_inv);&lt;br /&gt;
&lt;br /&gt;
and and_gate_0(out[0],in_1_inv,in_0_inv);&lt;br /&gt;
&lt;br /&gt;
and and_gate_1(out[1],in_1_inv,in_0_nat);&lt;br /&gt;
&lt;br /&gt;
and and_gate_2(out[2],in_1_nat,in_0_inv);&lt;br /&gt;
&lt;br /&gt;
and and_gate_3(out[3],in_1_nat,in_0_nat);&lt;br /&gt;
	&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor - varianta cu assign, urmand schema (fisierul decodor_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v2&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
	// fiecare bit din iesire calculat independent&lt;br /&gt;
assign out[0] = ~in[0] &amp;amp; ~in[1];&lt;br /&gt;
assign out[1] = in[0] &amp;amp; ~in[1];&lt;br /&gt;
assign out[2] = ~in[0] &amp;amp; in[1];&lt;br /&gt;
assign out[3] = in[0] &amp;amp; in[1];&lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu assign, cu operatorul &amp;quot;?&amp;quot; (fisierul decodor_v3.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v3&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
// operatorul &amp;quot;?&amp;quot;: identic c/c++; (conditie) ? (if_true) : (if_flase);&lt;br /&gt;
&lt;br /&gt;
assign out = (in==0) ? // if in == 0 &lt;br /&gt;
				1 : // if true: out = 1 &lt;br /&gt;
				(in==1) ? // else, verifica alt if. &lt;br /&gt;
					2 : // if in !=0 si in == 1&lt;br /&gt;
					(in==2) ?&lt;br /&gt;
						4 :&lt;br /&gt;
						8; // last case in==3&lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu always cu if (fisierul decodor_v4.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v4&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out&lt;br /&gt;
	);						 &lt;br /&gt;
&lt;br /&gt;
always_comb // mereu cand se schimba orice semnal, se &amp;quot;executa&amp;quot; ce e mai jos; &lt;br /&gt;
            // always_comb genereaza un circuit combinational&lt;br /&gt;
begin	// begin si end pe post de acolade din c/c++; delimiteaza if/else si altele asemenea; inclusiv always cu totul&lt;br /&gt;
	if(in == 0)&lt;br /&gt;
		begin // nota autorului: eu prefer sa pun begin/end asa. ele se pot pune si dupa conditie sau aliniate altfel.&lt;br /&gt;
				// ^ preferinta personala legata de coding style, important e sa fiti consecventi in cum scrieti&lt;br /&gt;
		out = 1; &lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		begin&lt;br /&gt;
		if(in == 1)&lt;br /&gt;
			out = 2;	// fiind o singura instructiune, begin/end se poate omite (identic c/c++)&lt;br /&gt;
		else&lt;br /&gt;
			begin	// nota autorului: eu personal le pun mereu. in caz ca mai adaug linii in if dupa, sa fie deja puse&lt;br /&gt;
			if(in == 2)&lt;br /&gt;
				begin&lt;br /&gt;
				out = 4;&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				begin&lt;br /&gt;
				out = 8;&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
end//end pt always&lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu always cu case (fisierul decodor_v5.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v5&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
always_comb&lt;br /&gt;
begin&lt;br /&gt;
	case(in) // functioneaza ca switch/case din c/c++; sintaxa usor diferita&lt;br /&gt;
		0: // if in == 0&lt;br /&gt;
			begin&lt;br /&gt;
			out = 1;&lt;br /&gt;
			end&lt;br /&gt;
		2&amp;#039;d1: // if in == 1;	2&amp;#039;d1 se traduce: pe 2 biti, in baza zece (eng: decimal, &amp;quot;d&amp;quot;), valoarea 1&lt;br /&gt;
			begin	// pt &amp;quot;0&amp;quot; de mai sus: daca nu se pune nimic se considera in baza zece.&lt;br /&gt;
			out = 2;&lt;br /&gt;
			end&lt;br /&gt;
		2&amp;#039;b10: // if in == 2;	scris in binar &amp;quot;b&amp;quot;, 2&amp;#039;b10 =&amp;gt; adica valoarea 2(10 binar) pe 2 biti &lt;br /&gt;
			begin&lt;br /&gt;
			out = 4;&lt;br /&gt;
			end&lt;br /&gt;
		2&amp;#039;h3: // if in == 3;	scris in hexa (baza 16 &amp;quot;h&amp;quot;, se poate si &amp;quot;x&amp;quot;), fiind numar mic, nu se vede diferenta fata de zecimal.&lt;br /&gt;
			begin&lt;br /&gt;
			out = 8;&lt;br /&gt;
			end&lt;br /&gt;
		default: // daca in == un caz netrat; &lt;br /&gt;
			begin // aici inutil pt ca am tratat toate cazurile posibile; pus ca exemplu de sintaxa &lt;br /&gt;
			out = 0;&lt;br /&gt;
			end&lt;br /&gt;
	endcase // orice &amp;quot;case&amp;quot; se inchide cu &amp;quot;endcase&amp;quot;&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;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu assign comportamental  (fisierul decodor_v6.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v6&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign out = 1 &amp;lt;&amp;lt; in; &lt;br /&gt;
	// prin shiftare&lt;br /&gt;
	// 1&amp;lt;&amp;lt;0 == 1 == 4&amp;#039;b0001; &lt;br /&gt;
	// 1&amp;lt;&amp;lt;1 == 2 == 4&amp;#039;b0010; &lt;br /&gt;
	// 1&amp;lt;&amp;lt;2 == 4 == 4&amp;#039;b0100; &lt;br /&gt;
	// 1&amp;lt;&amp;lt;3 == 8 == 4&amp;#039;b1000; &lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului top  (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
// observatie: &lt;br /&gt;
	// puteti da in vivado: rtl analysis -&amp;gt; open elaborated design -&amp;gt; schematic pentru a vedea desenul rezultat&lt;br /&gt;
	// puteti vedea ca moduri diferite de scriere produc aparitia a diferite primitive de sinteza&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out_v1, // fiecare varianta de decodor cu iesirea lui&lt;br /&gt;
		output logic [3:0] out_v2, // toate ar trebui sa scoata acelasi rezultat &lt;br /&gt;
		output logic [3:0] out_v3,&lt;br /&gt;
		output logic [3:0] out_v4,&lt;br /&gt;
		output logic [3:0] out_v5,&lt;br /&gt;
		output logic [3:0] out_v6&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v1 decodor_v1_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
decodor_v2 decodor_v2_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v2)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v3 decodor_v3_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v3)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v4 decodor_v4_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v4)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v5 decodor_v5_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v5)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
decodor_v6 decodor_v6_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v6)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
===Exercitiul 1: Multiplexorul===&lt;br /&gt;
&lt;br /&gt;
Multiplexorul (mux) este un circuit ce are rolul de a selecta una dintre intrari pentru ca aceasta sa ajunga la iesire.&lt;br /&gt;
&lt;br /&gt;
Imaginati-va o intersectie in care toate masinile vor sa se iasa catre aceasi strada. Pentru a evita accidente, este nevoie de un element de control, de selectie, prin care se hotaraste care dintre intrari este lasata sa ajunga la iesire, in respectivul moment de timp.&lt;br /&gt;
Multiplexorul poate fi de asemenea vazut ca un comutator.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 1:&amp;#039;&amp;#039;&amp;#039; conceptul de baza al multiplexarii este absolut vital si o sa apara des in multe zone ale ingineriei si la materii foarte diferite. &lt;br /&gt;
Ca niste mici exemple, el se foloseste in:&lt;br /&gt;
:a) telecomunicatii - cine are voie sa comunice pe un fir la un moment de timp &lt;br /&gt;
:b) internet - routere - cine trimite pachetele tcp/ip catre destinatia x&lt;br /&gt;
:c) panouri cu leduri - aprindere pe rand a ledurilor (de la instalatii de craciun pana la ecrane/televizoare care aprind randurile alternativ)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 2:&amp;#039;&amp;#039;&amp;#039; numarul de intrari maxim posibile este 2^(nr_biti_selectie)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 3:&amp;#039;&amp;#039;&amp;#039; multiplexoarele pot avea intrarile date si iesirea pe mai multi biti.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 4:&amp;#039;&amp;#039;&amp;#039; este de ajutor sa incepeti sa vedeti circuitele ca avand o cale de date ce sunt procesate si o cale de control care decide cum se face asta.&lt;br /&gt;
Aici calea de date este alcatuita din intrari si iesire, iar calea de control din firele de selectie. &lt;br /&gt;
Acest principiu se propaga si in arhitectura microprocesoarelor unde vor aparea magistrale si memorii de date/instructiuni.&lt;br /&gt;
&lt;br /&gt;
Pornind de la exemplul oferit, implementati multiplexorul in cat mai multe variante.&lt;br /&gt;
&lt;br /&gt;
Multiplexorul cu 2 intrari pe un bit fiecare (mux elementar) este desenat in figurile de mai jos: cum este vazut din exterior (prima figura) si alcatuirea lui interna (a doua figura). &lt;br /&gt;
&lt;br /&gt;
[[Fișier:mux2_general.png ‎| 300px]]&lt;br /&gt;
[[Fișier:mux2_schema_interna.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 10ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_mux2.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: Implementati un mux4 (multiplexor cu 4 intrari)===&lt;br /&gt;
&lt;br /&gt;
Interfata lui este ca in figura de mai jos. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:mux_general.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Pentru varianta lui structurala, mux4 se construieste din mai multe mux2 legate corespunzator. Incercati sa construiti voi aceasta schema.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 10ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_mux4.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Demultiplexorul===&lt;br /&gt;
&lt;br /&gt;
Demultiplexorul (demux) este un circuit ce are rolul de a selecta catre care iesire se va duce intrarea. &lt;br /&gt;
Imaginati-va o intersectie in care intra o singura masina si trebuie sa decida daca iese catre stanga/inainte/dreapta. 	&lt;br /&gt;
&lt;br /&gt;
Pentru acest exercitiu se va implementa un demux2 (cu 2 iesiri).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 1&amp;#039;&amp;#039;&amp;#039;: celelalte iesiri, cele neselectate iau valoarea 0.&lt;br /&gt;
	&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 2&amp;#039;&amp;#039;&amp;#039;: numarul de iesiri maxim posibile este 2^(nr_biti_selectie)&lt;br /&gt;
&lt;br /&gt;
Interfata demultiplexorului este data mai jos. Incercati sa construiti acest circuit in cat mai multe variante de sintaxa posibile (minim 4).	&lt;br /&gt;
&lt;br /&gt;
[[Fișier:demux2_general.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda pentru a vedea functionarea demultiplexorului.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Sumatorul===&lt;br /&gt;
&lt;br /&gt;
Sumatorul are rolul de a scoate la iesire suma celor 2 intrari.&lt;br /&gt;
&lt;br /&gt;
Uzual el mai are si intrare si iesire de &amp;quot;carry&amp;quot; adica de transport (cand se depaseste baza de numarare si e nevoie de inca o cifra, ex in zecimal: 88 + 20 = 108; apare o cifra in plus, cifra sutelor). &lt;br /&gt;
&lt;br /&gt;
[[Fișier:sumator_8b_general.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Observatie: desi scrierea cu assign si + este cea mai usoara si clara pentru un sumator, si celelalte moduri de scriere sunt posibile.&lt;br /&gt;
La aceasta scriere, daca se doresta ca sumatorul sa aiba carry out, sumatorul se poate face cu un bit mai mare decat intrarile, iar acel bit sa fie conectat la carry out. Practic, obtii un rezultat pe &amp;quot;n&amp;quot; biti + un bit de depasire, anume msb-ul. &lt;br /&gt;
&lt;br /&gt;
Generati formele de unda necesare testarii sumatorului pe 8b.&lt;br /&gt;
&lt;br /&gt;
Pentru a vedea pas cu pas cum se construieste un sumator pe 8b puteti parcurge urmatoarea platforma de laborator: [https://wiki.dcae.pub.ro/images/0/0f/Cid_gan_sumator_aplicatia_2.pdf Sumator.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Comparatorul===&lt;br /&gt;
&lt;br /&gt;
Comparatorul are rolul de a vedea relatia dintre cele 2 intrari ale sale, daca cele 2 numere sunt egale, daca primul e mai mic sau mai mare. &lt;br /&gt;
&lt;br /&gt;
Astfel el poate avea 3 iesiri dintre care se activeaza doar una: &lt;br /&gt;
:- iesire de egalitate&lt;br /&gt;
:- iesire de in0 &amp;lt; in1 &lt;br /&gt;
:- iesire de in0 &amp;gt; in1 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
Se mai poate face si o varianta de comparator cu 2 iesiri, asa cum veti studia la arhitectura microprocesoarelor.&lt;br /&gt;
:- iesire de egalitate&lt;br /&gt;
:- iesire care este 0 daca in0&amp;lt;in1 sau 1 daca in0&amp;gt;in1&lt;br /&gt;
&lt;br /&gt;
Aceasta abordare este folosita la AMP la flag-urile din procesoare, folosind operatia de scadere si flag-urile de &amp;quot;zero&amp;quot; si &amp;quot;negativ&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Scrieti modulul de comparator, in ambele variante de interfata. Intrarile pot avea oricat de multi biti (comparator mai mic sau mai mare), pentru acest exercitiu sa il faceti pe 4b.&lt;br /&gt;
&lt;br /&gt;
Scrieti un testbench care sa genereze toate combinatiile posibile de date de la intrare. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Discutie&amp;#039;&amp;#039;&amp;#039;: Daca acest comparator are datele pe 32b sau mai mult (sau daca circuitul devine mult mai complex), nu se mai poate face o astfel de testare exhaustiva a combinatiilor posibile de date de la intrare pentru ca simularea ar dura prea mult. De situatia asta se ocupa inginerii de verificare ce lucreaza in paralel cu inginerii de design. Pentru mai multe detalii puteti cauta &amp;quot;constrained random functional verification&amp;quot;. Incercati sa identificati cazurile/situatiile ce ar trebui testate pentru un comparator pe 32b inainte de a spune ca acesta functioneaza corect (minim 10).&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=7937</id>
		<title>CID aplicatii 2 : Instantiere si porti logice</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=7937"/>
		<updated>2025-02-25T09:27:19Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exercitiul 3: AND4 din AND2 aranjat pe lung (nu arbore) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie: incapsulare si instantiere==&lt;br /&gt;
Unitatile constructive de baza din care se formeaza circuitele digitale se numesc porti logice. Acestea implementeaza functii logice si prin conectarea mai multor astfel de circuite simple complexitatea unui circuit poate creste pana la nivelul procesoarelor actuale. Pentru a putea controla cresterea complexitatii in proiectarea unui circuit de dimensiuni mari se folosesc 2 concepte cheie: &lt;br /&gt;
&lt;br /&gt;
1) incapsularea functiei dorite intr-un modul&lt;br /&gt;
&lt;br /&gt;
2) instantierea unor module mai mici si asamblarea acestora pentru a forma un modul mai mare. &lt;br /&gt;
&lt;br /&gt;
Incapsularea se refera la a grupa elementele ce alcatuiesc o anumita functionalitate intr-un modul. Aceste elemente pot la randul lor sa fie alte module.&lt;br /&gt;
Instantierea (asemanator cu POO) se refera la a apela un modul deja scris pentru a fi folosit efectiv in circuitul curent. &lt;br /&gt;
Pentru a face o analogie cu programarea, cand se declara o variabila (sau un obiect), tipul variabilei este echivalent cu modulul si numele ei este numele instantei.&lt;br /&gt;
&lt;br /&gt;
Pentru a intelege aceste concepte se da circuitul de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_instantiere.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1) Notatie aici: Numele modulului este scris in interior. &lt;br /&gt;
&lt;br /&gt;
2) Notatie aici: Numele instantei este scris deasupra.&lt;br /&gt;
&lt;br /&gt;
3) Idee fundamentala: prin instantierea si incapsularea unor circuite simple, mici, apar circuite mai complexe.&lt;br /&gt;
&lt;br /&gt;
4) Idei esentiale (daca vreuna e neclara consultati cadrul didactic): &lt;br /&gt;
&lt;br /&gt;
:a) &amp;quot;modul_2&amp;quot; este instantiat o singura data in tot proiecul, iar instanta se cheama &amp;quot;x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:b) &amp;quot;modul_2&amp;quot; are o intrare numita &amp;quot;in0&amp;quot; si o iesire numita &amp;quot;out0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:c) &amp;quot;modul_2&amp;quot; este instantiat in cadrul &amp;quot;modul_6&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:d) Modulul cel mai mare, ce cuprinde toata functionalitatea dorita a sistemului (aici &amp;quot;modul_6&amp;quot;) se numeste uzual top.&lt;br /&gt;
&lt;br /&gt;
:e) Instanta top-ului care apare atunci cand se doreste testarea sa in simulare intr-un testbench (tb) se numeste uzual DUT (design under test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:f) &amp;quot;modul_0&amp;quot; apare instantiat de 3 ori. Circuitul final, cuprinde 3 subcircuite de tip &amp;quot;modul_0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:g) La nivel de top, instanta sa se cheama &amp;quot;b&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
:h) La nivel de &amp;quot;modul_5&amp;quot;, cele 2 instante se cheama &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:i) &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot; sunt 2 circuite fizice diferite chiar daca ambele sunt de tipul &amp;quot;modul_0&amp;quot;. Fiind instante ale aceluiasi modul, deci identice in alcatuire, luate separat ele fac acelasi lucru. Luate in contextul lui &amp;quot;modul_5&amp;quot;, &amp;quot;a&amp;quot; genereaza datele de pe firul &amp;quot;w0&amp;quot; si &amp;quot;c&amp;quot; genereaza datele pentru iesire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:j) circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_1&amp;quot; (instantiat in &amp;quot;modul_5&amp;quot;) este complet diferit de circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_0&amp;quot; (instantiat in top). Este permis ca ele sa aiba acelasi nume (cele 2 instante) deoarece se afla in locatii diferite. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:k) Identic, mai multe module au o intrare numita &amp;quot;in_0&amp;quot;. La sinteza circuitului nu se face confuzie intre acestea deoarece fiecare e vazut la nivelul altei instante.&lt;br /&gt;
&lt;br /&gt;
:l) Identic, firele de legatura &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:m) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w2&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;b&amp;quot; la intrarea &amp;quot;in2&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:n) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;x&amp;quot; la intrarea &amp;quot;in1&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:o) La nivelul &amp;quot;modul_5&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea instantei &amp;quot;b&amp;quot; la intrarea instantei &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:Pentru claritatea desenului, respectivele intrari si iesiri nu au fost denumite. In cod este obligatoriu ca ele sa fie definite si denumite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:p) La nivelul &amp;quot;top&amp;quot;, &amp;quot;in0&amp;quot;,&amp;quot;in1&amp;quot;,&amp;quot;in2&amp;quot;,&amp;quot;in3&amp;quot;,&amp;quot;in4&amp;quot; si &amp;quot;out0&amp;quot; formeaza interfata modulului (semnalele care intra sau ies din modul).&lt;br /&gt;
&lt;br /&gt;
:q) La nivelul &amp;quot;top&amp;quot;, &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;, &amp;quot;w2&amp;quot; sunt fire interne de legatura.&lt;br /&gt;
&lt;br /&gt;
:r) La nivelul &amp;quot;top&amp;quot;, firul &amp;quot;in3&amp;quot; este conectat ca intrare pentru 3 submodule.&lt;br /&gt;
&lt;br /&gt;
==Teorie: testarea circuitelor==&lt;br /&gt;
Pentru a se testa functionarea corecta a circuitului final, acesta este instantiat intr-un modul numit &amp;quot;test_bench&amp;quot; sau &amp;quot;tb&amp;quot;. Acest modul este folosit strict in simulare. &lt;br /&gt;
Testarea unui circuit are loc conform schemei urmatoare: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_tb.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Generarea datelor de intrare se va face asemanator cu laboratorul 1.&lt;br /&gt;
&lt;br /&gt;
Voi veti avea rolul modelului ideal si al comparatorului datelor de iesire, uitandu-va la datele de intrare veti calcula iesirea corecta si apoi veti compara aceasta valoare cu raspunsul circuitului ce se testeaza.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In cazul unui sistem automat, se genereaza mesaje de eroare sau mesaje ca functionarea este in regula.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Observatie: proiectarea si verificarea sunt 2 domenii diferite, firmele avand departamente separate pentru acestea. &lt;br /&gt;
&lt;br /&gt;
Proiectarea/Design se ocupa cu scrierea in Verilog/SystemVerilog a modului de top si toate modulele ce se afla in acesta, avand ca scop final realizarea fizica pe placa a unui circuit. &lt;br /&gt;
&lt;br /&gt;
Verificarea se ocupa de scrierea in SystemVerilog (limbaj format din Verilog cu concepte de POO) a modului de testbench si generarea de stimuli si scenarii care sa testeze functionarea design-ului.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: porti logice==&lt;br /&gt;
Portile logice folosite uzual, impreuna cu tabelele lor de adevar si reprezentarea grafica sunt date mai jos.&lt;br /&gt;
&lt;br /&gt;
Se folosesc porti logice cu 1 sau 2 intrari, cele cu mai mult de 2 intrari fiind construite din acestea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tip !! Simbol !! Tabel de adevăr !! Tip !! Simbol !! Tabel de adevăr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Buffer/Repetor&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:Buffer_gate.png|Buffer symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOT&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:not.png|NOT symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || NOT A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;AND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:and.png|AND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A AND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NAND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nand.png|NAND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NAND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;OR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:or.png|OR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A OR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nor.png|NOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xor.png|XOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XNOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xnor.png|XNOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XNOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Despre FPGA==&lt;br /&gt;
FPGA-ul (Field-Programmable Gate Array) este un circuit programabil, capabil sa implementeze circuite definit de utilizator. El este format dintr-o matrice de blocuri programabile, interconectate intre ele printr-o serie de conexiuni la randul lor programabile.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cand se doreste implementarea unui circuit pe FPGA, acesta urmeaza urmatoarele etape: &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Elaborarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care codul SystemVerilog este transformat intr-un circuit la nivel de porti si registre (netlist) si este independent de modelul de FPGA folosit. &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Sinteza&amp;#039;&amp;#039;&amp;#039; este procesul în care se realizează transformarea circuitului descris într-un netlist dependent de tehnologie. Se vor folosi la acest pas primitivele disponibile pe FPGA.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Implementarea&amp;#039;&amp;#039;&amp;#039; este procesul în care se preia netlist-ul ce conține primitivele FPGA și modul lor de interconectare realizat la pasul de sinteză și se realizează maparea lor efectivă în FPGA (place and route).&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Generarea Bitstream-ului&amp;#039;&amp;#039;&amp;#039; este procesul prin care informatiile din implementare sunt asamblate intr-un singur fisier.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Programarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care fisierul generat anterior este trimis efectiv catre placa cu FPGA (prin USB) unde determina modificarea valorilor si conexiunilor interne din aceasta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O introducere mai detaliata poate fi gasita aici : [[FPGA - Introducere]].&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Fpgaimg.PNG|600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Pentru a putea controla circuitul propus si a putea vedea rezultatele, intrarile si iesirile (input si output din module) in/din acesta trebuie conectate la pini fizici ai FPGA-ului care sunt conectati la butoane/switch-uri/leduri.&lt;br /&gt;
* Conexiunile dintre butoane/switch-uri si pinii FPGA sunt fixe. La fel si cele intre pinii FPGA si LED-uri. (in functie de PCB)&lt;br /&gt;
* Conexiunile dintre porturile modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; si pinii FPGA sunt configurabile. (in functie de noi, prin fisierul XDC)&lt;br /&gt;
* Legarea porturilor modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; la pinii fizici ai FPGA se realizeaza prin configurarea conexiunilor din FPGA conform contrangerilor de I/O pe care le vom mentiona in proiect, inainte de sinteza.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 1: Analiza circuitelor cu porti===&lt;br /&gt;
Fie urmatorul circuit alcatuit din porti logice:&lt;br /&gt;
 [[Fișier:Mux2_schema_interna_2.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Se doreste exprimarea circuitului de mai sus ca formula de tip: iesire = f(intrari). &lt;br /&gt;
&lt;br /&gt;
Pentru asta, abordarea consta in a porni de la iesire si a merge pas cu pas catre intrari, asa cum este exemplificat mai jos. Se vor folosi simbolurile &amp;quot;~&amp;quot; pentru NOT, &amp;quot;&amp;amp;&amp;quot; pentru AND, &amp;quot;|&amp;quot; pentru OR.&lt;br /&gt;
:pas1: out0 = ?&lt;br /&gt;
:pas2: out0 = w1 | w2&lt;br /&gt;
:pas3: out0 = w1 | ( ? )&lt;br /&gt;
:pas4: out0 = w1 | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas5: out0 = ( ? ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas6: out0 = ( in0 &amp;amp; w0 ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas7: out0 = ( in0 &amp;amp; ( ? ) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas8: out0 = ( in0 &amp;amp; (~sel) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: NAND2 din AND2 si NOT===&lt;br /&gt;
In urmatorul exemplu se implementeaza o poarta NAND din o poarta AND si o poarta NOT. &lt;br /&gt;
&lt;br /&gt;
Codul de mai jos exemplifica ideea de instantiere si contine comentarii legate de sintaxa SystemVerilog necesara.&lt;br /&gt;
&lt;br /&gt;
In mod uzual fisierele sunt denumite dupa modulul ce se afla in ele, in fiecare fisier fiind un singur modul.&lt;br /&gt;
&lt;br /&gt;
Schema circuitul care se doreste a fi creat este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_exemplu_rezolvat.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii NOT (fisierul not_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
// comentarii cu &amp;quot;//&amp;quot; sau cu /* .... */ ;&lt;br /&gt;
/* &lt;br /&gt;
	ca in c/c++ &lt;br /&gt;
*/ &lt;br /&gt;
&lt;br /&gt;
module not_gate	// cuvant cheie &amp;quot;module&amp;quot; apoi numele modulului (asemanator clase din c++)&lt;br /&gt;
	( // intre paranteze se pune interfata (firele care intra sau ies din modul)&lt;br /&gt;
		input logic in0,         // in0 este o intrare =&amp;gt; input&lt;br /&gt;
		output logic out0	// out0 este o intrare =&amp;gt; output&lt;br /&gt;
	); // aici &amp;quot;;&amp;quot; sa nu il uitati&lt;br /&gt;
&lt;br /&gt;
assign out0 = ~in0;	// cuvant cheie assign; &lt;br /&gt;
					// semnalele pot lua valoare prin assign&lt;br /&gt;
					// ~ e semnul pentru negatie pe biti (ca in c/c++)&lt;br /&gt;
&lt;br /&gt;
endmodule // cuvant cheie &amp;quot;endmodule&amp;quot;. orice module se inchide cu endmodule.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii AND (fisierul and_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and_gate&lt;br /&gt;
	(&lt;br /&gt;
		input logic in0,	// aici sunt 2 intrari &lt;br /&gt;
		input logic in1,	&lt;br /&gt;
		output logic out0&lt;br /&gt;
	); // nu conteaza ordinea in care sunt puse intrarile si iesirile.&lt;br /&gt;
			// uzual si pentru usurinta se ordoneaza si grupeaza dupa functionalitate&lt;br /&gt;
			// in cazul de mai sus, am pus intai intrarile, apoi iesirile.&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 &amp;amp; in1; // operatia propriu zisa &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului top (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic a,&lt;br /&gt;
		input logic b,&lt;br /&gt;
		output logic c&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic w0;    //declarat un fir intern de legatura &lt;br /&gt;
    &lt;br /&gt;
and_gate and_gate_0	// instantiere: nume_modul nume_instanta (asemanator int x din c/c++)&lt;br /&gt;
	(&lt;br /&gt;
		.in0(a), // la intrarea &amp;quot;in0&amp;quot; a instantei &amp;quot;and_gate_0&amp;quot;  se conecteaza firul &amp;quot;a&amp;quot; din top&lt;br /&gt;
		.in1(b), // grija ca &amp;quot;in0&amp;quot;, &amp;quot;in1&amp;quot;, &amp;quot;out0&amp;quot; sa existe in declararea modulului &amp;quot;and_gate&amp;quot;&lt;br /&gt;
		.out0(w0) // grija ca &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;w0&amp;quot; sa existe la nivelul modulului in care se face instantierea&lt;br /&gt;
	);    &lt;br /&gt;
    &lt;br /&gt;
not_gate not_gate_0&lt;br /&gt;
	(&lt;br /&gt;
		.in0(w0), // &amp;quot;w0&amp;quot; care iese din &amp;quot;and_gate_0&amp;quot; intra in &amp;quot;not_gate_0&amp;quot;&lt;br /&gt;
		.out0(c) // &amp;quot;c&amp;quot; care iese din &amp;quot;not_gate_0&amp;quot; iese din modulul &amp;quot;top&amp;quot; (e iesire in interfata de sus)&lt;br /&gt;
	);   // se poate scrie si &amp;quot;.in0(w0),.out0(c)&amp;quot; dar se prefera fiecare fir pe randul sau (lizibilitate si loc de comentarii pt design-uri complexe)&lt;br /&gt;
	// Observatie: la varianta de mai sus de instantiere, nu conteaza ordinea firelor. &lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
not_gate not_gate_0		&lt;br /&gt;
	(				// se poate instantia si in forma prescurtata ca aici &lt;br /&gt;
		w0,				// in acest caz se pun conexiunile in ordinea in care sunt declarate intrarile si iesirile din modul&lt;br /&gt;
		c	// NU se recomanda stilul asta de instantiere&lt;br /&gt;
	); 			// apar greseli frecvent la ordinea firelor si la numarul lor, &lt;br /&gt;
*/				// mai ales daca modulul e complex si are multe intrari si intrari&lt;br /&gt;
 &lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Echivalent se pot folosi si &amp;quot;primitive&amp;quot; SystemVerilog pentru scrierea top-ului.&lt;br /&gt;
&lt;br /&gt;
Primitivele sunt circuite care exista deja in limbaj, folosite atunci cand se doreste o descriere structurala a circuitului.&lt;br /&gt;
&lt;br /&gt;
In instantiere acestora, iesirea se pune prima, urmata de intrari.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; daca se doreste scrierea acestor porti de catre voi (ca mai sus), numele modulului nu trebuie sa fie un cuvant cheie ocupat de primitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v2&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
  &lt;br /&gt;
logic w0;&lt;br /&gt;
&lt;br /&gt;
and and_gate_0(w0,a,b);	// primitiva pentru poarta and&lt;br /&gt;
not not_gate_0(c,w0);  	// primitiva pentru poarta not&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fiind un modul simplu, intreaga functionalitate putea fi scrisa la nivel de &amp;quot;top&amp;quot; si simplificat ca mai jos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v3.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v3&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
   &lt;br /&gt;
assign c = ~ (a &amp;amp; b); // a si b, negate&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Testarea circuitul se face printr-un testbench, acesta fiind:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea testbench-ului (fisierul top_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module top_tb(); // din/in tb nu intra si iese nimic. niciodata.&lt;br /&gt;
&lt;br /&gt;
logic a_tb;	&lt;br /&gt;
logic b_tb;	&lt;br /&gt;
logic c_tb;	&lt;br /&gt;
&lt;br /&gt;
top dut	// instantierea modulului de tip &amp;quot;top&amp;quot; sub numele &amp;quot;dut&amp;quot; &lt;br /&gt;
	(&lt;br /&gt;
		.a(a_tb),&lt;br /&gt;
		.b(b_tb),&lt;br /&gt;
		.c(c_tb)&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin // in loc de { ... } din c/c++, in SystemVerilog se pune begin ... end &lt;br /&gt;
	#10;		// dupa 10 unitati de timp &lt;br /&gt;
	a_tb = 0;		// a_tb ia valoarea 0&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;		// dupa inca 10 unitati de timp, deci in total la 20&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	&lt;br /&gt;
	#20 $stop();	// oprirea simularii &lt;br /&gt;
end //end pentru initial &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formele de unda rezultate din simulare se pot vedea mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:exemplu_rezolvat_nand_forme_de_unda.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In chenarul verde se pot observa instantele din simulare. &lt;br /&gt;
&lt;br /&gt;
Daca se doreste adaugarea de semnale noi pentru a fi vazute, se selecteaza modulul instantiat in care acestea se afla (chenar verde). &lt;br /&gt;
&lt;br /&gt;
Apoi, din chenarul rosu se aleg semnalele si se adauga prin click dreapta-&amp;gt;add to wave window. &lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara vizualizare, semnalele se pot grupa asa cum se vede in chenarul mov prin click dreapta-&amp;gt;new group.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se observa o functionare corecta circuitului, acesta fiind o poarta NAND. El scoate &amp;quot;0&amp;quot; cand ambele semnale de intrare sunt &amp;quot;1&amp;quot; si scoate &amp;quot;1&amp;quot; in rest.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea circuitului pe FPGA&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dupa ce circuitul a fost testat in simulare, se doreste punerea sa fizica pe placa FPGA. Pentru aceasta, se tine cont de urmatoarele.&lt;br /&gt;
&lt;br /&gt;
* Pentru a controla intrarile &amp;#039;&amp;#039;a&amp;#039;&amp;#039; si &amp;#039;&amp;#039;b&amp;#039;&amp;#039; ale circuitului &amp;#039;&amp;#039;&amp;#039;top&amp;#039;&amp;#039;, va trebui sa le conectam prin intermediul conexiunilor configurabile ale FPGA-ului la pini ce sunt mai departe conectati fizic la dispozitive ce pot controla valorile semnalelor (switch-uri, butoane).&lt;br /&gt;
* Pentru a observa valoarea iesirii, vom conecta semnalul de iesire &amp;#039;&amp;#039;c&amp;#039;&amp;#039;la un dispozitiv de observare, cum ar fi un LED, care va fi aprins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 1 si stins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 0.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:NAND2 FPGA.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru a realiza conectarea porturilor modulului &amp;#039;&amp;#039;top&amp;#039;&amp;#039; la pinii fizici ai FPGA ce sunt conectati mai departe la componentele de pe placa, va trebui sa specificam in utilitarul de sinteza maparea porturilor la acestia. Maparea se realizeaza prin mentionarea codurilor pinilor la care dorim conexiunea si poata numele de &amp;#039;&amp;#039;&amp;#039;constrangeri de I/O&amp;#039;&amp;#039;&amp;#039;. Aceste coduri sunt mentionate in documentatia placii de dezvoltare cu FPGA (in cazul nostru, Boolean Board) si pot fi regasite si in pagina [[Boolean Board - Pinout]].&lt;br /&gt;
&lt;br /&gt;
Conform schemei, la acest exemplu avem nevoie de codurile pinilor conectati mai departe la Switch0, Switch1 si LED0.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Daca intrarile si iesirile ar fi semnale pe mai multi biti, fiecare bit al intrarilor va fi conectat la cate un switch/buton si fiecare bit al iesirii va fi conectat la un LED. Acest lucru este necesar deoarece switch-urile/butoanele pot avea doar doua stari (0 si 1) si astfel pot controla un singur bit. La fel, un LED poate avea doar doua stari (0 - stins si 1 - aprins) si poate afisa starea unui singur bit.&lt;br /&gt;
&lt;br /&gt;
Dupa ce ati extras codurile necesare, urmati pasii descrisi in [[Tutorial_Vivado|tutorialul Vivado]]. &lt;br /&gt;
&lt;br /&gt;
Dupa programarea cu succes a placii, puteti testa functionalitatea circuitului prin modficarea valorilor switch-urilor si observarea starii LED-ului.&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
Pentru urmatoarele exercitii se doreste atat testarea designurilor prin simulare cat si punerea acestora pe placa. Legat de placa, intrarile vor fi conectate la butoane, iar iesirile la leduri. Se va consulta tabelul cu pini disponibili ([[Boolean Board - Pinout]].).&lt;br /&gt;
&lt;br /&gt;
Exista moduri mai rapide de a scrie functionalitatea dorita (vezi exemplu), dar tema principala a acestui laborator este instantierea, asa ca sunteti rugati sa respectati desenele si sa instantiati fiecare poarta individual.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: AND4 din AND2=== &lt;br /&gt;
&lt;br /&gt;
Acest exercitiu arata cum se construieste o poarta AND cu 4 intrari din porti AND mai simple, cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca toate intrarile sunt &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_and4.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: OR4 din OR2===&lt;br /&gt;
&lt;br /&gt;
Asemanator cu exercitiul anterior, se poate construi si o poarta or cu 4 intrari din porti or cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca oricare din intrari (cel putin una) este &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_or4_din_or2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: AND4 din AND2 aranjat in cascada (nu arbore)===&lt;br /&gt;
&lt;br /&gt;
In multe cazuri, aceeasi functionalitate poate fi atinsa prin circuite care arata diferit. &lt;br /&gt;
O alta varianta de a face o poarta AND cu 4 intrari este prezentata mai jos. &lt;br /&gt;
&lt;br /&gt;
Comparati cele 2 variante. &lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2_v2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: AND4 din NAND2===&lt;br /&gt;
&lt;br /&gt;
Orice poarta logica de baza poate fi construita doar din porti NAND sau doar din porti NOR. &lt;br /&gt;
&lt;br /&gt;
Desenati si implementati circuitul pentru o poarta AND4 din porti NAND cu 2 intrari. &lt;br /&gt;
&lt;br /&gt;
Tip: Incercati intai sa generati o poarta AND2 din NAND2.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: AND4 pe 4b din AND4 pe 1b===&lt;br /&gt;
&lt;br /&gt;
Se pot face operatii logice si pe mai multi biti deodata prin punerea in paralel a mai multor porti cu o singura iesire.&lt;br /&gt;
	Exemplu :&lt;br /&gt;
		pentru intrarile 0011 si 1110 iesirea va fi 0010&lt;br /&gt;
&lt;br /&gt;
Pentru exersarea instantierii si intelegerea circuitului din spatele operatilor multibit implementati acest circuit prin instantierea a 4 porti AND2 pe 1 bit intr-o poarta AND2 pe 4 biti.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v1.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns):&lt;br /&gt;
 &lt;br /&gt;
[[Fișier:Wavedrom_and4_4b.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
Exista si un mod mai rapid si simplu de a scrie aceasta functionalitate, grupand intrarile si iesirile in &amp;quot;bus&amp;quot;-uri, ca in codul de mai jos.&lt;br /&gt;
Acest mod de a grupa firele este desenat mai jos.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Fisierul and4_4b.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and4_4b&lt;br /&gt;
	(&lt;br /&gt;
		input logic [3:0] in0,	// in0 are 4b, de la bit 3 la bit 0 inclusiv &lt;br /&gt;
		input logic [3:0] in1,	// se noteaza msb:lsb (most significant bit: least significant bit) (echivalent cu conceptul de cifra sutelor, cifra unitatilor, pt binar)&lt;br /&gt;
		input logic [3:0] in2,&lt;br /&gt;
		input logic [3:0] in3,&lt;br /&gt;
		output logic [3:0] out0&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
assign out0 = in0 &amp;amp; in1 &amp;amp; in2 &amp;amp; in3;&lt;br /&gt;
	&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Desenati schemele logice pentru urmatoarele circuite:===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;a) Schema 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema1 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f, g;&lt;br /&gt;
	&lt;br /&gt;
	logic w1;&lt;br /&gt;
	logic w2;&lt;br /&gt;
	&lt;br /&gt;
	and P1 ( w1, a, c );&lt;br /&gt;
	or P2 ( f, w1, w2, d);&lt;br /&gt;
	not P3 (w2, b);&lt;br /&gt;
	and P4 (g, w1, b, d);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observatie: In versiunea veche de verilog (si s-a pastrat si in cea curenta), se pot specifica directiile porturilor si in exteriorul parantezelor, ca mai sus. &lt;br /&gt;
Aceasta scriere NU este recomandata. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;b) Schema 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema2 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f;&lt;br /&gt;
	&lt;br /&gt;
	logic w1, w2;&lt;br /&gt;
	&lt;br /&gt;
	nand P1 ( w1, a, b ), P2 (w2, c, d);&lt;br /&gt;
	and P3 ( f, w1, w2);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; asemanator cu C/C++, se pot face declaratii in aceeasi linie a mai multor &amp;quot;variabile&amp;quot;, aici fire sau instante, cum se poate vedea la w1 si w2 (ambele fiind fire) sau la P1 si P2 (ambele fiind porti nand).&lt;br /&gt;
Aceasta scriere NU este recomandata.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=7936</id>
		<title>CID aplicatii 2 : Instantiere si porti logice</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=7936"/>
		<updated>2025-02-25T09:25:54Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Exemplul 2: NAND2 din AND2 si NOT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie: incapsulare si instantiere==&lt;br /&gt;
Unitatile constructive de baza din care se formeaza circuitele digitale se numesc porti logice. Acestea implementeaza functii logice si prin conectarea mai multor astfel de circuite simple complexitatea unui circuit poate creste pana la nivelul procesoarelor actuale. Pentru a putea controla cresterea complexitatii in proiectarea unui circuit de dimensiuni mari se folosesc 2 concepte cheie: &lt;br /&gt;
&lt;br /&gt;
1) incapsularea functiei dorite intr-un modul&lt;br /&gt;
&lt;br /&gt;
2) instantierea unor module mai mici si asamblarea acestora pentru a forma un modul mai mare. &lt;br /&gt;
&lt;br /&gt;
Incapsularea se refera la a grupa elementele ce alcatuiesc o anumita functionalitate intr-un modul. Aceste elemente pot la randul lor sa fie alte module.&lt;br /&gt;
Instantierea (asemanator cu POO) se refera la a apela un modul deja scris pentru a fi folosit efectiv in circuitul curent. &lt;br /&gt;
Pentru a face o analogie cu programarea, cand se declara o variabila (sau un obiect), tipul variabilei este echivalent cu modulul si numele ei este numele instantei.&lt;br /&gt;
&lt;br /&gt;
Pentru a intelege aceste concepte se da circuitul de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_instantiere.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1) Notatie aici: Numele modulului este scris in interior. &lt;br /&gt;
&lt;br /&gt;
2) Notatie aici: Numele instantei este scris deasupra.&lt;br /&gt;
&lt;br /&gt;
3) Idee fundamentala: prin instantierea si incapsularea unor circuite simple, mici, apar circuite mai complexe.&lt;br /&gt;
&lt;br /&gt;
4) Idei esentiale (daca vreuna e neclara consultati cadrul didactic): &lt;br /&gt;
&lt;br /&gt;
:a) &amp;quot;modul_2&amp;quot; este instantiat o singura data in tot proiecul, iar instanta se cheama &amp;quot;x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:b) &amp;quot;modul_2&amp;quot; are o intrare numita &amp;quot;in0&amp;quot; si o iesire numita &amp;quot;out0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:c) &amp;quot;modul_2&amp;quot; este instantiat in cadrul &amp;quot;modul_6&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:d) Modulul cel mai mare, ce cuprinde toata functionalitatea dorita a sistemului (aici &amp;quot;modul_6&amp;quot;) se numeste uzual top.&lt;br /&gt;
&lt;br /&gt;
:e) Instanta top-ului care apare atunci cand se doreste testarea sa in simulare intr-un testbench (tb) se numeste uzual DUT (design under test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:f) &amp;quot;modul_0&amp;quot; apare instantiat de 3 ori. Circuitul final, cuprinde 3 subcircuite de tip &amp;quot;modul_0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:g) La nivel de top, instanta sa se cheama &amp;quot;b&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
:h) La nivel de &amp;quot;modul_5&amp;quot;, cele 2 instante se cheama &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:i) &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot; sunt 2 circuite fizice diferite chiar daca ambele sunt de tipul &amp;quot;modul_0&amp;quot;. Fiind instante ale aceluiasi modul, deci identice in alcatuire, luate separat ele fac acelasi lucru. Luate in contextul lui &amp;quot;modul_5&amp;quot;, &amp;quot;a&amp;quot; genereaza datele de pe firul &amp;quot;w0&amp;quot; si &amp;quot;c&amp;quot; genereaza datele pentru iesire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:j) circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_1&amp;quot; (instantiat in &amp;quot;modul_5&amp;quot;) este complet diferit de circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_0&amp;quot; (instantiat in top). Este permis ca ele sa aiba acelasi nume (cele 2 instante) deoarece se afla in locatii diferite. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:k) Identic, mai multe module au o intrare numita &amp;quot;in_0&amp;quot;. La sinteza circuitului nu se face confuzie intre acestea deoarece fiecare e vazut la nivelul altei instante.&lt;br /&gt;
&lt;br /&gt;
:l) Identic, firele de legatura &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:m) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w2&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;b&amp;quot; la intrarea &amp;quot;in2&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:n) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;x&amp;quot; la intrarea &amp;quot;in1&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:o) La nivelul &amp;quot;modul_5&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea instantei &amp;quot;b&amp;quot; la intrarea instantei &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:Pentru claritatea desenului, respectivele intrari si iesiri nu au fost denumite. In cod este obligatoriu ca ele sa fie definite si denumite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:p) La nivelul &amp;quot;top&amp;quot;, &amp;quot;in0&amp;quot;,&amp;quot;in1&amp;quot;,&amp;quot;in2&amp;quot;,&amp;quot;in3&amp;quot;,&amp;quot;in4&amp;quot; si &amp;quot;out0&amp;quot; formeaza interfata modulului (semnalele care intra sau ies din modul).&lt;br /&gt;
&lt;br /&gt;
:q) La nivelul &amp;quot;top&amp;quot;, &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;, &amp;quot;w2&amp;quot; sunt fire interne de legatura.&lt;br /&gt;
&lt;br /&gt;
:r) La nivelul &amp;quot;top&amp;quot;, firul &amp;quot;in3&amp;quot; este conectat ca intrare pentru 3 submodule.&lt;br /&gt;
&lt;br /&gt;
==Teorie: testarea circuitelor==&lt;br /&gt;
Pentru a se testa functionarea corecta a circuitului final, acesta este instantiat intr-un modul numit &amp;quot;test_bench&amp;quot; sau &amp;quot;tb&amp;quot;. Acest modul este folosit strict in simulare. &lt;br /&gt;
Testarea unui circuit are loc conform schemei urmatoare: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_tb.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Generarea datelor de intrare se va face asemanator cu laboratorul 1.&lt;br /&gt;
&lt;br /&gt;
Voi veti avea rolul modelului ideal si al comparatorului datelor de iesire, uitandu-va la datele de intrare veti calcula iesirea corecta si apoi veti compara aceasta valoare cu raspunsul circuitului ce se testeaza.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In cazul unui sistem automat, se genereaza mesaje de eroare sau mesaje ca functionarea este in regula.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Observatie: proiectarea si verificarea sunt 2 domenii diferite, firmele avand departamente separate pentru acestea. &lt;br /&gt;
&lt;br /&gt;
Proiectarea/Design se ocupa cu scrierea in Verilog/SystemVerilog a modului de top si toate modulele ce se afla in acesta, avand ca scop final realizarea fizica pe placa a unui circuit. &lt;br /&gt;
&lt;br /&gt;
Verificarea se ocupa de scrierea in SystemVerilog (limbaj format din Verilog cu concepte de POO) a modului de testbench si generarea de stimuli si scenarii care sa testeze functionarea design-ului.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: porti logice==&lt;br /&gt;
Portile logice folosite uzual, impreuna cu tabelele lor de adevar si reprezentarea grafica sunt date mai jos.&lt;br /&gt;
&lt;br /&gt;
Se folosesc porti logice cu 1 sau 2 intrari, cele cu mai mult de 2 intrari fiind construite din acestea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tip !! Simbol !! Tabel de adevăr !! Tip !! Simbol !! Tabel de adevăr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Buffer/Repetor&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:Buffer_gate.png|Buffer symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOT&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:not.png|NOT symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || NOT A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;AND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:and.png|AND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A AND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NAND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nand.png|NAND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NAND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;OR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:or.png|OR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A OR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nor.png|NOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xor.png|XOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XNOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xnor.png|XNOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XNOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Despre FPGA==&lt;br /&gt;
FPGA-ul (Field-Programmable Gate Array) este un circuit programabil, capabil sa implementeze circuite definit de utilizator. El este format dintr-o matrice de blocuri programabile, interconectate intre ele printr-o serie de conexiuni la randul lor programabile.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cand se doreste implementarea unui circuit pe FPGA, acesta urmeaza urmatoarele etape: &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Elaborarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care codul SystemVerilog este transformat intr-un circuit la nivel de porti si registre (netlist) si este independent de modelul de FPGA folosit. &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Sinteza&amp;#039;&amp;#039;&amp;#039; este procesul în care se realizează transformarea circuitului descris într-un netlist dependent de tehnologie. Se vor folosi la acest pas primitivele disponibile pe FPGA.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Implementarea&amp;#039;&amp;#039;&amp;#039; este procesul în care se preia netlist-ul ce conține primitivele FPGA și modul lor de interconectare realizat la pasul de sinteză și se realizează maparea lor efectivă în FPGA (place and route).&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Generarea Bitstream-ului&amp;#039;&amp;#039;&amp;#039; este procesul prin care informatiile din implementare sunt asamblate intr-un singur fisier.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Programarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care fisierul generat anterior este trimis efectiv catre placa cu FPGA (prin USB) unde determina modificarea valorilor si conexiunilor interne din aceasta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O introducere mai detaliata poate fi gasita aici : [[FPGA - Introducere]].&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Fpgaimg.PNG|600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Pentru a putea controla circuitul propus si a putea vedea rezultatele, intrarile si iesirile (input si output din module) in/din acesta trebuie conectate la pini fizici ai FPGA-ului care sunt conectati la butoane/switch-uri/leduri.&lt;br /&gt;
* Conexiunile dintre butoane/switch-uri si pinii FPGA sunt fixe. La fel si cele intre pinii FPGA si LED-uri. (in functie de PCB)&lt;br /&gt;
* Conexiunile dintre porturile modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; si pinii FPGA sunt configurabile. (in functie de noi, prin fisierul XDC)&lt;br /&gt;
* Legarea porturilor modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; la pinii fizici ai FPGA se realizeaza prin configurarea conexiunilor din FPGA conform contrangerilor de I/O pe care le vom mentiona in proiect, inainte de sinteza.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 1: Analiza circuitelor cu porti===&lt;br /&gt;
Fie urmatorul circuit alcatuit din porti logice:&lt;br /&gt;
 [[Fișier:Mux2_schema_interna_2.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Se doreste exprimarea circuitului de mai sus ca formula de tip: iesire = f(intrari). &lt;br /&gt;
&lt;br /&gt;
Pentru asta, abordarea consta in a porni de la iesire si a merge pas cu pas catre intrari, asa cum este exemplificat mai jos. Se vor folosi simbolurile &amp;quot;~&amp;quot; pentru NOT, &amp;quot;&amp;amp;&amp;quot; pentru AND, &amp;quot;|&amp;quot; pentru OR.&lt;br /&gt;
:pas1: out0 = ?&lt;br /&gt;
:pas2: out0 = w1 | w2&lt;br /&gt;
:pas3: out0 = w1 | ( ? )&lt;br /&gt;
:pas4: out0 = w1 | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas5: out0 = ( ? ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas6: out0 = ( in0 &amp;amp; w0 ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas7: out0 = ( in0 &amp;amp; ( ? ) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas8: out0 = ( in0 &amp;amp; (~sel) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: NAND2 din AND2 si NOT===&lt;br /&gt;
In urmatorul exemplu se implementeaza o poarta NAND din o poarta AND si o poarta NOT. &lt;br /&gt;
&lt;br /&gt;
Codul de mai jos exemplifica ideea de instantiere si contine comentarii legate de sintaxa SystemVerilog necesara.&lt;br /&gt;
&lt;br /&gt;
In mod uzual fisierele sunt denumite dupa modulul ce se afla in ele, in fiecare fisier fiind un singur modul.&lt;br /&gt;
&lt;br /&gt;
Schema circuitul care se doreste a fi creat este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_exemplu_rezolvat.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii NOT (fisierul not_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
// comentarii cu &amp;quot;//&amp;quot; sau cu /* .... */ ;&lt;br /&gt;
/* &lt;br /&gt;
	ca in c/c++ &lt;br /&gt;
*/ &lt;br /&gt;
&lt;br /&gt;
module not_gate	// cuvant cheie &amp;quot;module&amp;quot; apoi numele modulului (asemanator clase din c++)&lt;br /&gt;
	( // intre paranteze se pune interfata (firele care intra sau ies din modul)&lt;br /&gt;
		input logic in0,         // in0 este o intrare =&amp;gt; input&lt;br /&gt;
		output logic out0	// out0 este o intrare =&amp;gt; output&lt;br /&gt;
	); // aici &amp;quot;;&amp;quot; sa nu il uitati&lt;br /&gt;
&lt;br /&gt;
assign out0 = ~in0;	// cuvant cheie assign; &lt;br /&gt;
					// semnalele pot lua valoare prin assign&lt;br /&gt;
					// ~ e semnul pentru negatie pe biti (ca in c/c++)&lt;br /&gt;
&lt;br /&gt;
endmodule // cuvant cheie &amp;quot;endmodule&amp;quot;. orice module se inchide cu endmodule.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii AND (fisierul and_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and_gate&lt;br /&gt;
	(&lt;br /&gt;
		input logic in0,	// aici sunt 2 intrari &lt;br /&gt;
		input logic in1,	&lt;br /&gt;
		output logic out0&lt;br /&gt;
	); // nu conteaza ordinea in care sunt puse intrarile si iesirile.&lt;br /&gt;
			// uzual si pentru usurinta se ordoneaza si grupeaza dupa functionalitate&lt;br /&gt;
			// in cazul de mai sus, am pus intai intrarile, apoi iesirile.&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 &amp;amp; in1; // operatia propriu zisa &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului top (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic a,&lt;br /&gt;
		input logic b,&lt;br /&gt;
		output logic c&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic w0;    //declarat un fir intern de legatura &lt;br /&gt;
    &lt;br /&gt;
and_gate and_gate_0	// instantiere: nume_modul nume_instanta (asemanator int x din c/c++)&lt;br /&gt;
	(&lt;br /&gt;
		.in0(a), // la intrarea &amp;quot;in0&amp;quot; a instantei &amp;quot;and_gate_0&amp;quot;  se conecteaza firul &amp;quot;a&amp;quot; din top&lt;br /&gt;
		.in1(b), // grija ca &amp;quot;in0&amp;quot;, &amp;quot;in1&amp;quot;, &amp;quot;out0&amp;quot; sa existe in declararea modulului &amp;quot;and_gate&amp;quot;&lt;br /&gt;
		.out0(w0) // grija ca &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;w0&amp;quot; sa existe la nivelul modulului in care se face instantierea&lt;br /&gt;
	);    &lt;br /&gt;
    &lt;br /&gt;
not_gate not_gate_0&lt;br /&gt;
	(&lt;br /&gt;
		.in0(w0), // &amp;quot;w0&amp;quot; care iese din &amp;quot;and_gate_0&amp;quot; intra in &amp;quot;not_gate_0&amp;quot;&lt;br /&gt;
		.out0(c) // &amp;quot;c&amp;quot; care iese din &amp;quot;not_gate_0&amp;quot; iese din modulul &amp;quot;top&amp;quot; (e iesire in interfata de sus)&lt;br /&gt;
	);   // se poate scrie si &amp;quot;.in0(w0),.out0(c)&amp;quot; dar se prefera fiecare fir pe randul sau (lizibilitate si loc de comentarii pt design-uri complexe)&lt;br /&gt;
	// Observatie: la varianta de mai sus de instantiere, nu conteaza ordinea firelor. &lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
not_gate not_gate_0		&lt;br /&gt;
	(				// se poate instantia si in forma prescurtata ca aici &lt;br /&gt;
		w0,				// in acest caz se pun conexiunile in ordinea in care sunt declarate intrarile si iesirile din modul&lt;br /&gt;
		c	// NU se recomanda stilul asta de instantiere&lt;br /&gt;
	); 			// apar greseli frecvent la ordinea firelor si la numarul lor, &lt;br /&gt;
*/				// mai ales daca modulul e complex si are multe intrari si intrari&lt;br /&gt;
 &lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Echivalent se pot folosi si &amp;quot;primitive&amp;quot; SystemVerilog pentru scrierea top-ului.&lt;br /&gt;
&lt;br /&gt;
Primitivele sunt circuite care exista deja in limbaj, folosite atunci cand se doreste o descriere structurala a circuitului.&lt;br /&gt;
&lt;br /&gt;
In instantiere acestora, iesirea se pune prima, urmata de intrari.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; daca se doreste scrierea acestor porti de catre voi (ca mai sus), numele modulului nu trebuie sa fie un cuvant cheie ocupat de primitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v2&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
  &lt;br /&gt;
logic w0;&lt;br /&gt;
&lt;br /&gt;
and and_gate_0(w0,a,b);	// primitiva pentru poarta and&lt;br /&gt;
not not_gate_0(c,w0);  	// primitiva pentru poarta not&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fiind un modul simplu, intreaga functionalitate putea fi scrisa la nivel de &amp;quot;top&amp;quot; si simplificat ca mai jos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v3.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v3&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
   &lt;br /&gt;
assign c = ~ (a &amp;amp; b); // a si b, negate&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Testarea circuitul se face printr-un testbench, acesta fiind:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea testbench-ului (fisierul top_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module top_tb(); // din/in tb nu intra si iese nimic. niciodata.&lt;br /&gt;
&lt;br /&gt;
logic a_tb;	&lt;br /&gt;
logic b_tb;	&lt;br /&gt;
logic c_tb;	&lt;br /&gt;
&lt;br /&gt;
top dut	// instantierea modulului de tip &amp;quot;top&amp;quot; sub numele &amp;quot;dut&amp;quot; &lt;br /&gt;
	(&lt;br /&gt;
		.a(a_tb),&lt;br /&gt;
		.b(b_tb),&lt;br /&gt;
		.c(c_tb)&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin // in loc de { ... } din c/c++, in SystemVerilog se pune begin ... end &lt;br /&gt;
	#10;		// dupa 10 unitati de timp &lt;br /&gt;
	a_tb = 0;		// a_tb ia valoarea 0&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;		// dupa inca 10 unitati de timp, deci in total la 20&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	&lt;br /&gt;
	#20 $stop();	// oprirea simularii &lt;br /&gt;
end //end pentru initial &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formele de unda rezultate din simulare se pot vedea mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:exemplu_rezolvat_nand_forme_de_unda.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In chenarul verde se pot observa instantele din simulare. &lt;br /&gt;
&lt;br /&gt;
Daca se doreste adaugarea de semnale noi pentru a fi vazute, se selecteaza modulul instantiat in care acestea se afla (chenar verde). &lt;br /&gt;
&lt;br /&gt;
Apoi, din chenarul rosu se aleg semnalele si se adauga prin click dreapta-&amp;gt;add to wave window. &lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara vizualizare, semnalele se pot grupa asa cum se vede in chenarul mov prin click dreapta-&amp;gt;new group.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se observa o functionare corecta circuitului, acesta fiind o poarta NAND. El scoate &amp;quot;0&amp;quot; cand ambele semnale de intrare sunt &amp;quot;1&amp;quot; si scoate &amp;quot;1&amp;quot; in rest.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea circuitului pe FPGA&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dupa ce circuitul a fost testat in simulare, se doreste punerea sa fizica pe placa FPGA. Pentru aceasta, se tine cont de urmatoarele.&lt;br /&gt;
&lt;br /&gt;
* Pentru a controla intrarile &amp;#039;&amp;#039;a&amp;#039;&amp;#039; si &amp;#039;&amp;#039;b&amp;#039;&amp;#039; ale circuitului &amp;#039;&amp;#039;&amp;#039;top&amp;#039;&amp;#039;, va trebui sa le conectam prin intermediul conexiunilor configurabile ale FPGA-ului la pini ce sunt mai departe conectati fizic la dispozitive ce pot controla valorile semnalelor (switch-uri, butoane).&lt;br /&gt;
* Pentru a observa valoarea iesirii, vom conecta semnalul de iesire &amp;#039;&amp;#039;c&amp;#039;&amp;#039;la un dispozitiv de observare, cum ar fi un LED, care va fi aprins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 1 si stins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 0.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:NAND2 FPGA.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru a realiza conectarea porturilor modulului &amp;#039;&amp;#039;top&amp;#039;&amp;#039; la pinii fizici ai FPGA ce sunt conectati mai departe la componentele de pe placa, va trebui sa specificam in utilitarul de sinteza maparea porturilor la acestia. Maparea se realizeaza prin mentionarea codurilor pinilor la care dorim conexiunea si poata numele de &amp;#039;&amp;#039;&amp;#039;constrangeri de I/O&amp;#039;&amp;#039;&amp;#039;. Aceste coduri sunt mentionate in documentatia placii de dezvoltare cu FPGA (in cazul nostru, Boolean Board) si pot fi regasite si in pagina [[Boolean Board - Pinout]].&lt;br /&gt;
&lt;br /&gt;
Conform schemei, la acest exemplu avem nevoie de codurile pinilor conectati mai departe la Switch0, Switch1 si LED0.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Daca intrarile si iesirile ar fi semnale pe mai multi biti, fiecare bit al intrarilor va fi conectat la cate un switch/buton si fiecare bit al iesirii va fi conectat la un LED. Acest lucru este necesar deoarece switch-urile/butoanele pot avea doar doua stari (0 si 1) si astfel pot controla un singur bit. La fel, un LED poate avea doar doua stari (0 - stins si 1 - aprins) si poate afisa starea unui singur bit.&lt;br /&gt;
&lt;br /&gt;
Dupa ce ati extras codurile necesare, urmati pasii descrisi in [[Tutorial_Vivado|tutorialul Vivado]]. &lt;br /&gt;
&lt;br /&gt;
Dupa programarea cu succes a placii, puteti testa functionalitatea circuitului prin modficarea valorilor switch-urilor si observarea starii LED-ului.&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
Pentru urmatoarele exercitii se doreste atat testarea designurilor prin simulare cat si punerea acestora pe placa. Legat de placa, intrarile vor fi conectate la butoane, iar iesirile la leduri. Se va consulta tabelul cu pini disponibili ([[Boolean Board - Pinout]].).&lt;br /&gt;
&lt;br /&gt;
Exista moduri mai rapide de a scrie functionalitatea dorita (vezi exemplu), dar tema principala a acestui laborator este instantierea, asa ca sunteti rugati sa respectati desenele si sa instantiati fiecare poarta individual.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: AND4 din AND2=== &lt;br /&gt;
&lt;br /&gt;
Acest exercitiu arata cum se construieste o poarta AND cu 4 intrari din porti AND mai simple, cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca toate intrarile sunt &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_and4.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: OR4 din OR2===&lt;br /&gt;
&lt;br /&gt;
Asemanator cu exercitiul anterior, se poate construi si o poarta or cu 4 intrari din porti or cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca oricare din intrari (cel putin una) este &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_or4_din_or2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: AND4 din AND2 aranjat pe lung (nu arbore)===&lt;br /&gt;
&lt;br /&gt;
In multe cazuri, aceeasi functionalitate poate fi atinsa prin circuite care arata diferit. &lt;br /&gt;
O alta varianta de a face o poarta AND cu 4 intrari este prezentata mai jos. &lt;br /&gt;
&lt;br /&gt;
Comparati cele 2 variante. &lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2_v2.png ‎| 600px]]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: AND4 din NAND2===&lt;br /&gt;
&lt;br /&gt;
Orice poarta logica de baza poate fi construita doar din porti NAND sau doar din porti NOR. &lt;br /&gt;
&lt;br /&gt;
Desenati si implementati circuitul pentru o poarta AND4 din porti NAND cu 2 intrari. &lt;br /&gt;
&lt;br /&gt;
Tip: Incercati intai sa generati o poarta AND2 din NAND2.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: AND4 pe 4b din AND4 pe 1b===&lt;br /&gt;
&lt;br /&gt;
Se pot face operatii logice si pe mai multi biti deodata prin punerea in paralel a mai multor porti cu o singura iesire.&lt;br /&gt;
	Exemplu :&lt;br /&gt;
		pentru intrarile 0011 si 1110 iesirea va fi 0010&lt;br /&gt;
&lt;br /&gt;
Pentru exersarea instantierii si intelegerea circuitului din spatele operatilor multibit implementati acest circuit prin instantierea a 4 porti AND2 pe 1 bit intr-o poarta AND2 pe 4 biti.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v1.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns):&lt;br /&gt;
 &lt;br /&gt;
[[Fișier:Wavedrom_and4_4b.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
Exista si un mod mai rapid si simplu de a scrie aceasta functionalitate, grupand intrarile si iesirile in &amp;quot;bus&amp;quot;-uri, ca in codul de mai jos.&lt;br /&gt;
Acest mod de a grupa firele este desenat mai jos.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Fisierul and4_4b.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and4_4b&lt;br /&gt;
	(&lt;br /&gt;
		input logic [3:0] in0,	// in0 are 4b, de la bit 3 la bit 0 inclusiv &lt;br /&gt;
		input logic [3:0] in1,	// se noteaza msb:lsb (most significant bit: least significant bit) (echivalent cu conceptul de cifra sutelor, cifra unitatilor, pt binar)&lt;br /&gt;
		input logic [3:0] in2,&lt;br /&gt;
		input logic [3:0] in3,&lt;br /&gt;
		output logic [3:0] out0&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
assign out0 = in0 &amp;amp; in1 &amp;amp; in2 &amp;amp; in3;&lt;br /&gt;
	&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Desenati schemele logice pentru urmatoarele circuite:===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;a) Schema 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema1 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f, g;&lt;br /&gt;
	&lt;br /&gt;
	logic w1;&lt;br /&gt;
	logic w2;&lt;br /&gt;
	&lt;br /&gt;
	and P1 ( w1, a, c );&lt;br /&gt;
	or P2 ( f, w1, w2, d);&lt;br /&gt;
	not P3 (w2, b);&lt;br /&gt;
	and P4 (g, w1, b, d);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observatie: In versiunea veche de verilog (si s-a pastrat si in cea curenta), se pot specifica directiile porturilor si in exteriorul parantezelor, ca mai sus. &lt;br /&gt;
Aceasta scriere NU este recomandata. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;b) Schema 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema2 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f;&lt;br /&gt;
	&lt;br /&gt;
	logic w1, w2;&lt;br /&gt;
	&lt;br /&gt;
	nand P1 ( w1, a, b ), P2 (w2, c, d);&lt;br /&gt;
	and P3 ( f, w1, w2);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; asemanator cu C/C++, se pot face declaratii in aceeasi linie a mai multor &amp;quot;variabile&amp;quot;, aici fire sau instante, cum se poate vedea la w1 si w2 (ambele fiind fire) sau la P1 si P2 (ambele fiind porti nand).&lt;br /&gt;
Aceasta scriere NU este recomandata.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=7935</id>
		<title>CID aplicatii 2 : Instantiere si porti logice</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=7935"/>
		<updated>2025-02-25T09:19:36Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: /* Teorie: incapsulare si instantiere */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie: incapsulare si instantiere==&lt;br /&gt;
Unitatile constructive de baza din care se formeaza circuitele digitale se numesc porti logice. Acestea implementeaza functii logice si prin conectarea mai multor astfel de circuite simple complexitatea unui circuit poate creste pana la nivelul procesoarelor actuale. Pentru a putea controla cresterea complexitatii in proiectarea unui circuit de dimensiuni mari se folosesc 2 concepte cheie: &lt;br /&gt;
&lt;br /&gt;
1) incapsularea functiei dorite intr-un modul&lt;br /&gt;
&lt;br /&gt;
2) instantierea unor module mai mici si asamblarea acestora pentru a forma un modul mai mare. &lt;br /&gt;
&lt;br /&gt;
Incapsularea se refera la a grupa elementele ce alcatuiesc o anumita functionalitate intr-un modul. Aceste elemente pot la randul lor sa fie alte module.&lt;br /&gt;
Instantierea (asemanator cu POO) se refera la a apela un modul deja scris pentru a fi folosit efectiv in circuitul curent. &lt;br /&gt;
Pentru a face o analogie cu programarea, cand se declara o variabila (sau un obiect), tipul variabilei este echivalent cu modulul si numele ei este numele instantei.&lt;br /&gt;
&lt;br /&gt;
Pentru a intelege aceste concepte se da circuitul de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_instantiere.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1) Notatie aici: Numele modulului este scris in interior. &lt;br /&gt;
&lt;br /&gt;
2) Notatie aici: Numele instantei este scris deasupra.&lt;br /&gt;
&lt;br /&gt;
3) Idee fundamentala: prin instantierea si incapsularea unor circuite simple, mici, apar circuite mai complexe.&lt;br /&gt;
&lt;br /&gt;
4) Idei esentiale (daca vreuna e neclara consultati cadrul didactic): &lt;br /&gt;
&lt;br /&gt;
:a) &amp;quot;modul_2&amp;quot; este instantiat o singura data in tot proiecul, iar instanta se cheama &amp;quot;x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:b) &amp;quot;modul_2&amp;quot; are o intrare numita &amp;quot;in0&amp;quot; si o iesire numita &amp;quot;out0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:c) &amp;quot;modul_2&amp;quot; este instantiat in cadrul &amp;quot;modul_6&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:d) Modulul cel mai mare, ce cuprinde toata functionalitatea dorita a sistemului (aici &amp;quot;modul_6&amp;quot;) se numeste uzual top.&lt;br /&gt;
&lt;br /&gt;
:e) Instanta top-ului care apare atunci cand se doreste testarea sa in simulare intr-un testbench (tb) se numeste uzual DUT (design under test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:f) &amp;quot;modul_0&amp;quot; apare instantiat de 3 ori. Circuitul final, cuprinde 3 subcircuite de tip &amp;quot;modul_0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:g) La nivel de top, instanta sa se cheama &amp;quot;b&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
:h) La nivel de &amp;quot;modul_5&amp;quot;, cele 2 instante se cheama &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:i) &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot; sunt 2 circuite fizice diferite chiar daca ambele sunt de tipul &amp;quot;modul_0&amp;quot;. Fiind instante ale aceluiasi modul, deci identice in alcatuire, luate separat ele fac acelasi lucru. Luate in contextul lui &amp;quot;modul_5&amp;quot;, &amp;quot;a&amp;quot; genereaza datele de pe firul &amp;quot;w0&amp;quot; si &amp;quot;c&amp;quot; genereaza datele pentru iesire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:j) circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_1&amp;quot; (instantiat in &amp;quot;modul_5&amp;quot;) este complet diferit de circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_0&amp;quot; (instantiat in top). Este permis ca ele sa aiba acelasi nume (cele 2 instante) deoarece se afla in locatii diferite. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:k) Identic, mai multe module au o intrare numita &amp;quot;in_0&amp;quot;. La sinteza circuitului nu se face confuzie intre acestea deoarece fiecare e vazut la nivelul altei instante.&lt;br /&gt;
&lt;br /&gt;
:l) Identic, firele de legatura &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:m) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w2&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;b&amp;quot; la intrarea &amp;quot;in2&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:n) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;x&amp;quot; la intrarea &amp;quot;in1&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:o) La nivelul &amp;quot;modul_5&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea instantei &amp;quot;b&amp;quot; la intrarea instantei &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:Pentru claritatea desenului, respectivele intrari si iesiri nu au fost denumite. In cod este obligatoriu ca ele sa fie definite si denumite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:p) La nivelul &amp;quot;top&amp;quot;, &amp;quot;in0&amp;quot;,&amp;quot;in1&amp;quot;,&amp;quot;in2&amp;quot;,&amp;quot;in3&amp;quot;,&amp;quot;in4&amp;quot; si &amp;quot;out0&amp;quot; formeaza interfata modulului (semnalele care intra sau ies din modul).&lt;br /&gt;
&lt;br /&gt;
:q) La nivelul &amp;quot;top&amp;quot;, &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;, &amp;quot;w2&amp;quot; sunt fire interne de legatura.&lt;br /&gt;
&lt;br /&gt;
:r) La nivelul &amp;quot;top&amp;quot;, firul &amp;quot;in3&amp;quot; este conectat ca intrare pentru 3 submodule.&lt;br /&gt;
&lt;br /&gt;
==Teorie: testarea circuitelor==&lt;br /&gt;
Pentru a se testa functionarea corecta a circuitului final, acesta este instantiat intr-un modul numit &amp;quot;test_bench&amp;quot; sau &amp;quot;tb&amp;quot;. Acest modul este folosit strict in simulare. &lt;br /&gt;
Testarea unui circuit are loc conform schemei urmatoare: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_tb.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Generarea datelor de intrare se va face asemanator cu laboratorul 1.&lt;br /&gt;
&lt;br /&gt;
Voi veti avea rolul modelului ideal si al comparatorului datelor de iesire, uitandu-va la datele de intrare veti calcula iesirea corecta si apoi veti compara aceasta valoare cu raspunsul circuitului ce se testeaza.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In cazul unui sistem automat, se genereaza mesaje de eroare sau mesaje ca functionarea este in regula.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Observatie: proiectarea si verificarea sunt 2 domenii diferite, firmele avand departamente separate pentru acestea. &lt;br /&gt;
&lt;br /&gt;
Proiectarea/Design se ocupa cu scrierea in Verilog/SystemVerilog a modului de top si toate modulele ce se afla in acesta, avand ca scop final realizarea fizica pe placa a unui circuit. &lt;br /&gt;
&lt;br /&gt;
Verificarea se ocupa de scrierea in SystemVerilog (limbaj format din Verilog cu concepte de POO) a modului de testbench si generarea de stimuli si scenarii care sa testeze functionarea design-ului.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: porti logice==&lt;br /&gt;
Portile logice folosite uzual, impreuna cu tabelele lor de adevar si reprezentarea grafica sunt date mai jos.&lt;br /&gt;
&lt;br /&gt;
Se folosesc porti logice cu 1 sau 2 intrari, cele cu mai mult de 2 intrari fiind construite din acestea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tip !! Simbol !! Tabel de adevăr !! Tip !! Simbol !! Tabel de adevăr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Buffer/Repetor&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:Buffer_gate.png|Buffer symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOT&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:not.png|NOT symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || NOT A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;AND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:and.png|AND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A AND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NAND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nand.png|NAND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NAND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;OR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:or.png|OR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A OR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nor.png|NOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xor.png|XOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XNOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xnor.png|XNOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XNOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Despre FPGA==&lt;br /&gt;
FPGA-ul (Field-Programmable Gate Array) este un circuit programabil, capabil sa implementeze circuite definit de utilizator. El este format dintr-o matrice de blocuri programabile, interconectate intre ele printr-o serie de conexiuni la randul lor programabile.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cand se doreste implementarea unui circuit pe FPGA, acesta urmeaza urmatoarele etape: &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Elaborarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care codul SystemVerilog este transformat intr-un circuit la nivel de porti si registre (netlist) si este independent de modelul de FPGA folosit. &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Sinteza&amp;#039;&amp;#039;&amp;#039; este procesul în care se realizează transformarea circuitului descris într-un netlist dependent de tehnologie. Se vor folosi la acest pas primitivele disponibile pe FPGA.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Implementarea&amp;#039;&amp;#039;&amp;#039; este procesul în care se preia netlist-ul ce conține primitivele FPGA și modul lor de interconectare realizat la pasul de sinteză și se realizează maparea lor efectivă în FPGA (place and route).&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Generarea Bitstream-ului&amp;#039;&amp;#039;&amp;#039; este procesul prin care informatiile din implementare sunt asamblate intr-un singur fisier.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Programarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care fisierul generat anterior este trimis efectiv catre placa cu FPGA (prin USB) unde determina modificarea valorilor si conexiunilor interne din aceasta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O introducere mai detaliata poate fi gasita aici : [[FPGA - Introducere]].&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Fpgaimg.PNG|600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Pentru a putea controla circuitul propus si a putea vedea rezultatele, intrarile si iesirile (input si output din module) in/din acesta trebuie conectate la pini fizici ai FPGA-ului care sunt conectati la butoane/switch-uri/leduri.&lt;br /&gt;
* Conexiunile dintre butoane/switch-uri si pinii FPGA sunt fixe. La fel si cele intre pinii FPGA si LED-uri. (in functie de PCB)&lt;br /&gt;
* Conexiunile dintre porturile modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; si pinii FPGA sunt configurabile. (in functie de noi, prin fisierul XDC)&lt;br /&gt;
* Legarea porturilor modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; la pinii fizici ai FPGA se realizeaza prin configurarea conexiunilor din FPGA conform contrangerilor de I/O pe care le vom mentiona in proiect, inainte de sinteza.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 1: Analiza circuitelor cu porti===&lt;br /&gt;
Fie urmatorul circuit alcatuit din porti logice:&lt;br /&gt;
 [[Fișier:Mux2_schema_interna_2.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Se doreste exprimarea circuitului de mai sus ca formula de tip: iesire = f(intrari). &lt;br /&gt;
&lt;br /&gt;
Pentru asta, abordarea consta in a porni de la iesire si a merge pas cu pas catre intrari, asa cum este exemplificat mai jos. Se vor folosi simbolurile &amp;quot;~&amp;quot; pentru NOT, &amp;quot;&amp;amp;&amp;quot; pentru AND, &amp;quot;|&amp;quot; pentru OR.&lt;br /&gt;
:pas1: out0 = ?&lt;br /&gt;
:pas2: out0 = w1 | w2&lt;br /&gt;
:pas3: out0 = w1 | ( ? )&lt;br /&gt;
:pas4: out0 = w1 | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas5: out0 = ( ? ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas6: out0 = ( in0 &amp;amp; w0 ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas7: out0 = ( in0 &amp;amp; ( ? ) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas8: out0 = ( in0 &amp;amp; (~sel) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: NAND2 din AND2 si NOT===&lt;br /&gt;
In urmatorul exemplu se implementeaza o poarta NAND din o poarta AND si o poarta NOT. &lt;br /&gt;
&lt;br /&gt;
Codul de mai jos exemplifica ideea de instantiere si contine comentarii legate de sintaxa SystemVerilog necesara.&lt;br /&gt;
&lt;br /&gt;
In mod uzual fisierele sunt denumite dupa modulul ce se afla in ele, in fiecare fisier fiind un singur modul.&lt;br /&gt;
&lt;br /&gt;
Schema circuitul care se doreste a fi creat este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_exemplu_rezolvat.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii NOT (fisierul not_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
// comentarii cu &amp;quot;//&amp;quot; sau cu /* .... */ ;&lt;br /&gt;
/* &lt;br /&gt;
	ca in c/c++ &lt;br /&gt;
*/ &lt;br /&gt;
&lt;br /&gt;
module not_gate	// cuvant cheie &amp;quot;module&amp;quot; apoi numele modulului (asemanator clase din c++)&lt;br /&gt;
	( // intre paranteze se pune interfata (firele care intra sau ies din modul)&lt;br /&gt;
		input logic in0,         // in0 este o intrare =&amp;gt; input&lt;br /&gt;
		output logic out0	// out0 este o intrare =&amp;gt; output&lt;br /&gt;
	); // aici &amp;quot;;&amp;quot; sa nu il uitati&lt;br /&gt;
&lt;br /&gt;
assign out0 = ~in0;	// cuvant cheie assign; &lt;br /&gt;
					// semnalele de tip wire (cum e out0) iau valoare prin assign&lt;br /&gt;
					// ~ e semnul pentru negatie pe biti (ca in c/c++)&lt;br /&gt;
&lt;br /&gt;
endmodule // cuvant cheie &amp;quot;endmodule&amp;quot;. orice module se inchide cu endmodule.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii AND (fisierul and_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and_gate&lt;br /&gt;
	(&lt;br /&gt;
		input logic in0,	// aici sunt 2 intrari &lt;br /&gt;
		input logic in1,	&lt;br /&gt;
		output logic out0&lt;br /&gt;
	); // nu conteaza ordinea in care sunt puse intrarile si iesirile.&lt;br /&gt;
			// uzual si pentru usurinta se ordoneaza si grupeaza dupa functionalitate&lt;br /&gt;
			// in cazul de mai sus, am pus intai intrarile, apoi iesirile.&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 &amp;amp; in1; // operatia propriu zisa &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului top (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic a,&lt;br /&gt;
		input logic b,&lt;br /&gt;
		output logic c&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic w0;    //declarat un fir intern de legatura &lt;br /&gt;
    &lt;br /&gt;
and_gate and_gate_0	// instantiere: nume_modul nume_instanta (asemanator int x din c/c++)&lt;br /&gt;
	(&lt;br /&gt;
		.in0(a), // la intrarea &amp;quot;in0&amp;quot; a instantei &amp;quot;and_gate_0&amp;quot;  se conecteaza firul &amp;quot;a&amp;quot; din top&lt;br /&gt;
		.in1(b), // grija ca &amp;quot;in0&amp;quot;, &amp;quot;in1&amp;quot;, &amp;quot;out0&amp;quot; sa existe in declararea modulului &amp;quot;and_gate&amp;quot;&lt;br /&gt;
		.out0(w0) // grija ca &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;w0&amp;quot; sa existe la nivelul modulului in care se face instantierea&lt;br /&gt;
	);    &lt;br /&gt;
    &lt;br /&gt;
not_gate not_gate_0&lt;br /&gt;
	(&lt;br /&gt;
		.in0(w0), // &amp;quot;w0&amp;quot; care iese din &amp;quot;and_gate_0&amp;quot; intra in &amp;quot;not_gate_0&amp;quot;&lt;br /&gt;
		.out0(c) // &amp;quot;c&amp;quot; care iese din &amp;quot;not_gate_0&amp;quot; iese din modulul &amp;quot;top&amp;quot; (e iesire in interfata de sus)&lt;br /&gt;
	);   // se poate scrie si &amp;quot;.in0(w0),.out0(c)&amp;quot; dar se prefera fiecare fir pe randul sau (lizibilitate si loc de comentarii pt design-uri complexe)&lt;br /&gt;
	// Observatie: la varianta de mai sus de instantiere, nu conteaza ordinea firelor. &lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
not_gate not_gate_0		&lt;br /&gt;
	(				// se poate instantia si in forma prescurtata ca aici &lt;br /&gt;
		w0,				// in acest caz se pun conexiunile in ordinea in care sunt declarate intrarile si iesirile din modul&lt;br /&gt;
		c	// NU se recomanda stilul asta de instantiere&lt;br /&gt;
	); 			// apar greseli frecvent la ordinea firelor, la numarul lor, &lt;br /&gt;
*/				// mai ales daca modulul e complex si are multe intrari si intrari&lt;br /&gt;
 &lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Echivalent se pot folosi si &amp;quot;primitive&amp;quot; SystemVerilog pentru scrierea top-ului.&lt;br /&gt;
&lt;br /&gt;
Primitivele sunt porti logice care exista deja in limbaj, folosite atunci cand se doreste o descriere structurala a circuitului.&lt;br /&gt;
&lt;br /&gt;
In instantiere acestora, iesirea se pune prima, urmata de intrari.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; daca se doreste scrierea acestor porti de catre voi (ca mai sus), numele modulului nu trebuie sa fie un cuvant cheie ocupat de primitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v2&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
  &lt;br /&gt;
wire w0;&lt;br /&gt;
&lt;br /&gt;
and and_gate_0(w0,a,b);	// primitiva pentru poarta and&lt;br /&gt;
not not_gate_0(c,w0);  	// primitiva pentru poarta not&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fiind un modul simplu, intreaga functionalitate putea fi scrisa la nivel de &amp;quot;top&amp;quot; si simplificat ca mai jos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v3.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v3&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
   &lt;br /&gt;
assign c = ~ (a &amp;amp; b); // a si b, negate&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Testarea circuitul se face printr-un testbench, acesta fiind:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea testbench-ului (fisierul top_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module top_tb(); // din/in tb nu intra si iese nimic. niciodata.&lt;br /&gt;
&lt;br /&gt;
logic a_tb;	&lt;br /&gt;
logic b_tb;	&lt;br /&gt;
logic c_tb;	&lt;br /&gt;
&lt;br /&gt;
top dut	// instantierea modulului de tip &amp;quot;top&amp;quot; sub numele &amp;quot;dut&amp;quot; &lt;br /&gt;
	(&lt;br /&gt;
		.a(a_tb),&lt;br /&gt;
		.b(b_tb),&lt;br /&gt;
		.c(c_tb)&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin // in loc de { ... } din c/c++, in SystemVerilog se pune begin ... end &lt;br /&gt;
	#10;		// dupa 10 unitati de timp &lt;br /&gt;
	a_tb = 0;		// a_tb ia valoarea 0&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;		// dupa inca 10 unitati de timp, deci in total la 20&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	&lt;br /&gt;
	#20 $stop();	// oprirea simularii &lt;br /&gt;
end //end pentru initial &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formele de unda rezultate din simulare se pot vedea mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:exemplu_rezolvat_nand_forme_de_unda.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In chenarul verde se pot observa instantele din simulare. &lt;br /&gt;
&lt;br /&gt;
Daca se doreste adaugarea de semnale noi pentru a fi vazute, se selecteaza modulul instantiat in care acestea se afla (chenar verde). &lt;br /&gt;
&lt;br /&gt;
Apoi, din chenarul rosu se aleg semnalele si se adauga prin click dreapta-&amp;gt;add to wave window. &lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara vizualizare, semnalele se pot grupa asa cum se vede in chenarul mov prin click dreapta-&amp;gt;new group.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se observa o functionare corecta circuitului, acesta fiind o poarta NAND. El scoate &amp;quot;0&amp;quot; cand ambele semnale de intrare sunt &amp;quot;1&amp;quot; si scoate &amp;quot;1&amp;quot; in rest.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea circuitului pe FPGA&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dupa ce circuitul a fost testat in simulare, se doreste punerea sa fizica pe placa FPGA. Pentru aceasta, se tine cont de urmatoarele.&lt;br /&gt;
&lt;br /&gt;
* Pentru a controla intrarile &amp;#039;&amp;#039;a&amp;#039;&amp;#039; si &amp;#039;&amp;#039;b&amp;#039;&amp;#039; ale circuitului &amp;#039;&amp;#039;&amp;#039;top&amp;#039;&amp;#039;, va trebui sa le conectam prin intermediul conexiunilor configurabile ale FPGA-ului la pini ce sunt mai departe conectati fizic la dispozitive ce pot controla valorile semnalelor (switch-uri, butoane).&lt;br /&gt;
* Pentru a observa valoarea iesirii, vom conecta semnalul de iesire &amp;#039;&amp;#039;c&amp;#039;&amp;#039;la un dispozitiv de observare, cum ar fi un LED, care va fi aprins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 1 si stins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 0.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:NAND2 FPGA.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru a realiza conectarea porturilor modulului &amp;#039;&amp;#039;top&amp;#039;&amp;#039; la pinii fizici ai FPGA ce sunt conectati mai departe la componentele de pe placa, va trebui sa specificam in utilitarul de sinteza maparea porturilor la acestia. Maparea se realizeaza prin mentionarea codurilor pinilor la care dorim conexiunea si poata numele de &amp;#039;&amp;#039;&amp;#039;constrangeri de I/O&amp;#039;&amp;#039;&amp;#039;. Aceste coduri sunt mentionate in documentatia placii de dezvoltare cu FPGA (in cazul nostru, Boolean Board) si pot fi regasite si in pagina [[Boolean Board - Pinout]].&lt;br /&gt;
&lt;br /&gt;
Conform schemei, la acest exemplu avem nevoie de codurile pinilor conectati mai departe la Switch0, Switch1 si LED0.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Daca intrarile si iesirile ar fi semnale pe mai multi biti, fiecare bit al intrarilor va fi conectat la cate un switch/buton si fiecare bit al iesirii va fi conectat la un LED. Acest lucru este necesar deoarece switch-urile/butoanele pot avea doar doua stari (0 si 1) si astfel pot controla un singur bit. La fel, un LED poate avea doar doua stari (0 - stins si 1 - aprins) si poate afisa starea unui singur bit.&lt;br /&gt;
&lt;br /&gt;
Dupa ce ati extras codurile necesare, urmati pasii descrisi in [[Tutorial_Vivado|tutorialul Vivado]]. &lt;br /&gt;
&lt;br /&gt;
Dupa programarea cu succes a placii, puteti testa functionalitatea circuitului prin modficarea valorilor switch-urilor si observarea starii LED-ului.&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
Pentru urmatoarele exercitii se doreste atat testarea designurilor prin simulare cat si punerea acestora pe placa. Legat de placa, intrarile vor fi conectate la butoane, iar iesirile la leduri. Se va consulta tabelul cu pini disponibili ([[Boolean Board - Pinout]].).&lt;br /&gt;
&lt;br /&gt;
Exista moduri mai rapide de a scrie functionalitatea dorita (vezi exemplu), dar tema principala a acestui laborator este instantierea, asa ca sunteti rugati sa respectati desenele si sa instantiati fiecare poarta individual.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: AND4 din AND2=== &lt;br /&gt;
&lt;br /&gt;
Acest exercitiu arata cum se construieste o poarta AND cu 4 intrari din porti AND mai simple, cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca toate intrarile sunt &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_and4.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: OR4 din OR2===&lt;br /&gt;
&lt;br /&gt;
Asemanator cu exercitiul anterior, se poate construi si o poarta or cu 4 intrari din porti or cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca oricare din intrari (cel putin una) este &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_or4_din_or2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: AND4 din AND2 aranjat pe lung (nu arbore)===&lt;br /&gt;
&lt;br /&gt;
In multe cazuri, aceeasi functionalitate poate fi atinsa prin circuite care arata diferit. &lt;br /&gt;
O alta varianta de a face o poarta AND cu 4 intrari este prezentata mai jos. &lt;br /&gt;
&lt;br /&gt;
Comparati cele 2 variante. &lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2_v2.png ‎| 600px]]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: AND4 din NAND2===&lt;br /&gt;
&lt;br /&gt;
Orice poarta logica de baza poate fi construita doar din porti NAND sau doar din porti NOR. &lt;br /&gt;
&lt;br /&gt;
Desenati si implementati circuitul pentru o poarta AND4 din porti NAND cu 2 intrari. &lt;br /&gt;
&lt;br /&gt;
Tip: Incercati intai sa generati o poarta AND2 din NAND2.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: AND4 pe 4b din AND4 pe 1b===&lt;br /&gt;
&lt;br /&gt;
Se pot face operatii logice si pe mai multi biti deodata prin punerea in paralel a mai multor porti cu o singura iesire.&lt;br /&gt;
	Exemplu :&lt;br /&gt;
		pentru intrarile 0011 si 1110 iesirea va fi 0010&lt;br /&gt;
&lt;br /&gt;
Pentru exersarea instantierii si intelegerea circuitului din spatele operatilor multibit implementati acest circuit prin instantierea a 4 porti AND2 pe 1 bit intr-o poarta AND2 pe 4 biti.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v1.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns):&lt;br /&gt;
 &lt;br /&gt;
[[Fișier:Wavedrom_and4_4b.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
Exista si un mod mai rapid si simplu de a scrie aceasta functionalitate, grupand intrarile si iesirile in &amp;quot;bus&amp;quot;-uri, ca in codul de mai jos.&lt;br /&gt;
Acest mod de a grupa firele este desenat mai jos.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Fisierul and4_4b.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and4_4b&lt;br /&gt;
	(&lt;br /&gt;
		input logic [3:0] in0,	// in0 are 4b, de la bit 3 la bit 0 inclusiv &lt;br /&gt;
		input logic [3:0] in1,	// se noteaza msb:lsb (most significant bit: least significant bit) (echivalent cu conceptul de cifra sutelor, cifra unitatilor, pt binar)&lt;br /&gt;
		input logic [3:0] in2,&lt;br /&gt;
		input logic [3:0] in3,&lt;br /&gt;
		output logic [3:0] out0&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
assign out0 = in0 &amp;amp; in1 &amp;amp; in2 &amp;amp; in3;&lt;br /&gt;
	&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Desenati schemele logice pentru urmatoarele circuite:===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;a) Schema 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema1 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f, g;&lt;br /&gt;
	&lt;br /&gt;
	logic w1;&lt;br /&gt;
	logic w2;&lt;br /&gt;
	&lt;br /&gt;
	and P1 ( w1, a, c );&lt;br /&gt;
	or P2 ( f, w1, w2, d);&lt;br /&gt;
	not P3 (w2, b);&lt;br /&gt;
	and P4 (g, w1, b, d);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observatie: In versiunea veche de verilog (si s-a pastrat si in cea curenta), se pot specifica directiile porturilor si in exteriorul parantezelor, ca mai sus. &lt;br /&gt;
Aceasta scriere NU este recomandata. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;b) Schema 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema2 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f;&lt;br /&gt;
	&lt;br /&gt;
	logic w1, w2;&lt;br /&gt;
	&lt;br /&gt;
	nand P1 ( w1, a, b ), P2 (w2, c, d);&lt;br /&gt;
	and P3 ( f, w1, w2);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; asemanator cu C/C++, se pot face declaratii in aceeasi linie a mai multor &amp;quot;variabile&amp;quot;, aici fire sau instante, cum se poate vedea la w1 si w2 (ambele fiind fire) sau la P1 si P2 (ambele fiind porti nand).&lt;br /&gt;
Aceasta scriere NU este recomandata.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=7934</id>
		<title>CID aplicatii 2 : Instantiere si porti logice</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_2_:_Instantiere_si_porti_logice&amp;diff=7934"/>
		<updated>2025-02-25T09:16:35Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie: incapsulare si instantiere==&lt;br /&gt;
Unitatile constructive de baza din care se formeaza circuitele digitale se numesc porti logice. Acestea implementeaza functii logice si prin conectarea mai multor astfel de circuite simple complexitatea unui circuit poate creste pana la nivelul procesoarelor actuale. Pentru a putea controla cresterea complexitatii in proiectarea unui circuit de dimensiuni mari se folosesc 2 concepte cheie: &lt;br /&gt;
&lt;br /&gt;
1) incapsularea functiei dorite intr-un modul&lt;br /&gt;
&lt;br /&gt;
2) instantierea unor module mai mici si asamblarea acestora pentru a forma un modul mai mare. &lt;br /&gt;
&lt;br /&gt;
Incapsularea se refera la a grupa elementele ce alcatuiesc o anumita functionalitate intre-un modul. Aceste elemente pot la randul lor sa fie alte module.&lt;br /&gt;
Instantierea (asemanator cu POO) se refera la a apela un modul deja scris pentru a fi folosit efectiv in circuitul curent. &lt;br /&gt;
Pentru a face o analogie cu programarea, cand se declara o variabila (sau un obiect), tipul variabilei este echivalent cu modulul si numele ei este numele instantei.&lt;br /&gt;
&lt;br /&gt;
Pentru a intelege aceste concepte se da circuitul de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_instantiere.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1) Notatie aici: Numele modulului este scris in interior. &lt;br /&gt;
&lt;br /&gt;
2) Notatie aici: Numele instantei este scris deasupra.&lt;br /&gt;
&lt;br /&gt;
3) Idee fundamentala: prin instantierea si incapsularea unor circuite simple, mici, apar circuite mai complexe.&lt;br /&gt;
&lt;br /&gt;
4) Idei esentiale (daca vreuna e neclara consultati cadrul didactic): &lt;br /&gt;
&lt;br /&gt;
:a) &amp;quot;modul_2&amp;quot; este instantiat o singura data in tot proiecul, iar instanta se cheama &amp;quot;x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:b) &amp;quot;modul_2&amp;quot; are o intrare numita &amp;quot;in0&amp;quot; si o iesire numita &amp;quot;out0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
:c) &amp;quot;modul_2&amp;quot; este instantiat in cadrul &amp;quot;modul_6&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:d) Modulul cel mai mare, ce cuprinde toata functionalitatea dorita a sistemului (aici &amp;quot;modul_6&amp;quot;) se numeste uzual top.&lt;br /&gt;
&lt;br /&gt;
:e) Instanta top-ului care apare atunci cand se doreste testarea sa in simulare intr-un testbench (tb) se numeste uzual DUT (design under test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:f) &amp;quot;modul_0&amp;quot; apare instantiat de 3 ori. Circuitul final, cuprinde 3 subcircuite de tip &amp;quot;modul_0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:g) La nivel de top, instanta sa se cheama &amp;quot;b&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
:h) La nivel de &amp;quot;modul_5&amp;quot;, cele 2 instante se cheama &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:i) &amp;quot;a&amp;quot; si &amp;quot;c&amp;quot; sunt 2 circuite fizice diferite chiar daca ambele sunt de tipul &amp;quot;modul_0&amp;quot;. Fiind instante ale aceluiasi modul, deci identice in alcatuire, luate separat ele fac acelasi lucru. Luate in contextul lui &amp;quot;modul_5&amp;quot;, &amp;quot;a&amp;quot; genereaza datele de pe firul &amp;quot;w0&amp;quot; si &amp;quot;c&amp;quot; genereaza datele pentru iesire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:j) circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_1&amp;quot; (instantiat in &amp;quot;modul_5&amp;quot;) este complet diferit de circuitul &amp;quot;b&amp;quot; de tip &amp;quot;modul_0&amp;quot; (instantiat in top). Este permis ca ele sa aiba acelasi nume (cele 2 instante) deoarece se afla in locatii diferite. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:k) Identic, mai multe module au o intrare numita &amp;quot;in_0&amp;quot;. La sinteza circuitului nu se face confuzie intre acestea deoarece fiecare e vazut la nivelul altei instante.&lt;br /&gt;
&lt;br /&gt;
:l) Identic, firele de legatura &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:m) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w2&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;b&amp;quot; la intrarea &amp;quot;in2&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:n) La nivelul &amp;quot;top&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea &amp;quot;out_0&amp;quot; a instantei &amp;quot;x&amp;quot; la intrarea &amp;quot;in1&amp;quot; a instantei &amp;quot;y&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:o) La nivelul &amp;quot;modul_5&amp;quot;, firul de legatura &amp;quot;w1&amp;quot; leaga iesirea instantei &amp;quot;b&amp;quot; la intrarea instantei &amp;quot;c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
:Pentru claritatea desenului, respectivele intrari si iesiri nu au fost denumite. In cod este obligatoriu ca ele sa fie definite si denumite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:p) La nivelul &amp;quot;top&amp;quot;, &amp;quot;in0&amp;quot;,&amp;quot;in1&amp;quot;,&amp;quot;in2&amp;quot;,&amp;quot;in3&amp;quot;,&amp;quot;in4&amp;quot; si &amp;quot;out0&amp;quot; formeaza interfata modulului (semnalele care intra sau ies din modul).&lt;br /&gt;
&lt;br /&gt;
:q) La nivelul &amp;quot;top&amp;quot;, &amp;quot;w0&amp;quot;, &amp;quot;w1&amp;quot;, &amp;quot;w2&amp;quot; sunt fire interne de legatura.&lt;br /&gt;
&lt;br /&gt;
:r) La nivelul &amp;quot;top&amp;quot;, firul &amp;quot;in3&amp;quot; este conectat ca intrare pentru 3 submodule.&lt;br /&gt;
&lt;br /&gt;
==Teorie: testarea circuitelor==&lt;br /&gt;
Pentru a se testa functionarea corecta a circuitului final, acesta este instantiat intr-un modul numit &amp;quot;test_bench&amp;quot; sau &amp;quot;tb&amp;quot;. Acest modul este folosit strict in simulare. &lt;br /&gt;
Testarea unui circuit are loc conform schemei urmatoare: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_principiu_tb.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Generarea datelor de intrare se va face asemanator cu laboratorul 1.&lt;br /&gt;
&lt;br /&gt;
Voi veti avea rolul modelului ideal si al comparatorului datelor de iesire, uitandu-va la datele de intrare veti calcula iesirea corecta si apoi veti compara aceasta valoare cu raspunsul circuitului ce se testeaza.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In cazul unui sistem automat, se genereaza mesaje de eroare sau mesaje ca functionarea este in regula.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Observatie: proiectarea si verificarea sunt 2 domenii diferite, firmele avand departamente separate pentru acestea. &lt;br /&gt;
&lt;br /&gt;
Proiectarea/Design se ocupa cu scrierea in Verilog/SystemVerilog a modului de top si toate modulele ce se afla in acesta, avand ca scop final realizarea fizica pe placa a unui circuit. &lt;br /&gt;
&lt;br /&gt;
Verificarea se ocupa de scrierea in SystemVerilog (limbaj format din Verilog cu concepte de POO) a modului de testbench si generarea de stimuli si scenarii care sa testeze functionarea design-ului.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: porti logice==&lt;br /&gt;
Portile logice folosite uzual, impreuna cu tabelele lor de adevar si reprezentarea grafica sunt date mai jos.&lt;br /&gt;
&lt;br /&gt;
Se folosesc porti logice cu 1 sau 2 intrari, cele cu mai mult de 2 intrari fiind construite din acestea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tip !! Simbol !! Tabel de adevăr !! Tip !! Simbol !! Tabel de adevăr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Buffer/Repetor&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:Buffer_gate.png|Buffer symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOT&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:not.png|NOT symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || NOT A&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;AND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:and.png|AND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A AND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NAND&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nand.png|NAND symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NAND B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;OR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:or.png|OR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A OR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;NOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:nor.png|NOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A NOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xor.png|XOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;XNOR&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| [[Image:xnor.png|XNOR symbol]]&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=right&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|colspan=2|&amp;#039;&amp;#039;&amp;#039;INTRARE&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;IEȘIRE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| A || B || A XNOR B&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Despre FPGA==&lt;br /&gt;
FPGA-ul (Field-Programmable Gate Array) este un circuit programabil, capabil sa implementeze circuite definit de utilizator. El este format dintr-o matrice de blocuri programabile, interconectate intre ele printr-o serie de conexiuni la randul lor programabile.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cand se doreste implementarea unui circuit pe FPGA, acesta urmeaza urmatoarele etape: &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Elaborarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care codul SystemVerilog este transformat intr-un circuit la nivel de porti si registre (netlist) si este independent de modelul de FPGA folosit. &lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Sinteza&amp;#039;&amp;#039;&amp;#039; este procesul în care se realizează transformarea circuitului descris într-un netlist dependent de tehnologie. Se vor folosi la acest pas primitivele disponibile pe FPGA.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Implementarea&amp;#039;&amp;#039;&amp;#039; este procesul în care se preia netlist-ul ce conține primitivele FPGA și modul lor de interconectare realizat la pasul de sinteză și se realizează maparea lor efectivă în FPGA (place and route).&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Generarea Bitstream-ului&amp;#039;&amp;#039;&amp;#039; este procesul prin care informatiile din implementare sunt asamblate intr-un singur fisier.&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;Programarea&amp;#039;&amp;#039;&amp;#039; este procesul prin care fisierul generat anterior este trimis efectiv catre placa cu FPGA (prin USB) unde determina modificarea valorilor si conexiunilor interne din aceasta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O introducere mai detaliata poate fi gasita aici : [[FPGA - Introducere]].&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Fpgaimg.PNG|600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatii:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Pentru a putea controla circuitul propus si a putea vedea rezultatele, intrarile si iesirile (input si output din module) in/din acesta trebuie conectate la pini fizici ai FPGA-ului care sunt conectati la butoane/switch-uri/leduri.&lt;br /&gt;
* Conexiunile dintre butoane/switch-uri si pinii FPGA sunt fixe. La fel si cele intre pinii FPGA si LED-uri. (in functie de PCB)&lt;br /&gt;
* Conexiunile dintre porturile modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; si pinii FPGA sunt configurabile. (in functie de noi, prin fisierul XDC)&lt;br /&gt;
* Legarea porturilor modulului &amp;#039;&amp;#039;Module&amp;#039;&amp;#039; la pinii fizici ai FPGA se realizeaza prin configurarea conexiunilor din FPGA conform contrangerilor de I/O pe care le vom mentiona in proiect, inainte de sinteza.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 1: Analiza circuitelor cu porti===&lt;br /&gt;
Fie urmatorul circuit alcatuit din porti logice:&lt;br /&gt;
 [[Fișier:Mux2_schema_interna_2.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Se doreste exprimarea circuitului de mai sus ca formula de tip: iesire = f(intrari). &lt;br /&gt;
&lt;br /&gt;
Pentru asta, abordarea consta in a porni de la iesire si a merge pas cu pas catre intrari, asa cum este exemplificat mai jos. Se vor folosi simbolurile &amp;quot;~&amp;quot; pentru NOT, &amp;quot;&amp;amp;&amp;quot; pentru AND, &amp;quot;|&amp;quot; pentru OR.&lt;br /&gt;
:pas1: out0 = ?&lt;br /&gt;
:pas2: out0 = w1 | w2&lt;br /&gt;
:pas3: out0 = w1 | ( ? )&lt;br /&gt;
:pas4: out0 = w1 | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas5: out0 = ( ? ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas6: out0 = ( in0 &amp;amp; w0 ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas7: out0 = ( in0 &amp;amp; ( ? ) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
:pas8: out0 = ( in0 &amp;amp; (~sel) ) | ( sel &amp;amp; in1 )&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: NAND2 din AND2 si NOT===&lt;br /&gt;
In urmatorul exemplu se implementeaza o poarta NAND din o poarta AND si o poarta NOT. &lt;br /&gt;
&lt;br /&gt;
Codul de mai jos exemplifica ideea de instantiere si contine comentarii legate de sintaxa SystemVerilog necesara.&lt;br /&gt;
&lt;br /&gt;
In mod uzual fisierele sunt denumite dupa modulul ce se afla in ele, in fiecare fisier fiind un singur modul.&lt;br /&gt;
&lt;br /&gt;
Schema circuitul care se doreste a fi creat este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_exemplu_rezolvat.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii NOT (fisierul not_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
// comentarii cu &amp;quot;//&amp;quot; sau cu /* .... */ ;&lt;br /&gt;
/* &lt;br /&gt;
	ca in c/c++ &lt;br /&gt;
*/ &lt;br /&gt;
&lt;br /&gt;
module not_gate	// cuvant cheie &amp;quot;module&amp;quot; apoi numele modulului (asemanator clase din c++)&lt;br /&gt;
	( // intre paranteze se pune interfata (firele care intra sau ies din modul)&lt;br /&gt;
		input logic in0,         // in0 este o intrare =&amp;gt; input&lt;br /&gt;
		output logic out0	// out0 este o intrare =&amp;gt; output&lt;br /&gt;
	); // aici &amp;quot;;&amp;quot; sa nu il uitati&lt;br /&gt;
&lt;br /&gt;
assign out0 = ~in0;	// cuvant cheie assign; &lt;br /&gt;
					// semnalele de tip wire (cum e out0) iau valoare prin assign&lt;br /&gt;
					// ~ e semnul pentru negatie pe biti (ca in c/c++)&lt;br /&gt;
&lt;br /&gt;
endmodule // cuvant cheie &amp;quot;endmodule&amp;quot;. orice module se inchide cu endmodule.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea portii AND (fisierul and_gate.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and_gate&lt;br /&gt;
	(&lt;br /&gt;
		input logic in0,	// aici sunt 2 intrari &lt;br /&gt;
		input logic in1,	&lt;br /&gt;
		output logic out0&lt;br /&gt;
	); // nu conteaza ordinea in care sunt puse intrarile si iesirile.&lt;br /&gt;
			// uzual si pentru usurinta se ordoneaza si grupeaza dupa functionalitate&lt;br /&gt;
			// in cazul de mai sus, am pus intai intrarile, apoi iesirile.&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 &amp;amp; in1; // operatia propriu zisa &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului top (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic a,&lt;br /&gt;
		input logic b,&lt;br /&gt;
		output logic c&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic w0;    //declarat un fir intern de legatura &lt;br /&gt;
    &lt;br /&gt;
and_gate and_gate_0	// instantiere: nume_modul nume_instanta (asemanator int x din c/c++)&lt;br /&gt;
	(&lt;br /&gt;
		.in0(a), // la intrarea &amp;quot;in0&amp;quot; a instantei &amp;quot;and_gate_0&amp;quot;  se conecteaza firul &amp;quot;a&amp;quot; din top&lt;br /&gt;
		.in1(b), // grija ca &amp;quot;in0&amp;quot;, &amp;quot;in1&amp;quot;, &amp;quot;out0&amp;quot; sa existe in declararea modulului &amp;quot;and_gate&amp;quot;&lt;br /&gt;
		.out0(w0) // grija ca &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;w0&amp;quot; sa existe la nivelul modulului in care se face instantierea&lt;br /&gt;
	);    &lt;br /&gt;
    &lt;br /&gt;
not_gate not_gate_0&lt;br /&gt;
	(&lt;br /&gt;
		.in0(w0), // &amp;quot;w0&amp;quot; care iese din &amp;quot;and_gate_0&amp;quot; intra in &amp;quot;not_gate_0&amp;quot;&lt;br /&gt;
		.out0(c) // &amp;quot;c&amp;quot; care iese din &amp;quot;not_gate_0&amp;quot; iese din modulul &amp;quot;top&amp;quot; (e iesire in interfata de sus)&lt;br /&gt;
	);   // se poate scrie si &amp;quot;.in0(w0),.out0(c)&amp;quot; dar se prefera fiecare fir pe randul sau (lizibilitate si loc de comentarii pt design-uri complexe)&lt;br /&gt;
	// Observatie: la varianta de mai sus de instantiere, nu conteaza ordinea firelor. &lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
not_gate not_gate_0		&lt;br /&gt;
	(				// se poate instantia si in forma prescurtata ca aici &lt;br /&gt;
		w0,				// in acest caz se pun conexiunile in ordinea in care sunt declarate intrarile si iesirile din modul&lt;br /&gt;
		c	// NU se recomanda stilul asta de instantiere&lt;br /&gt;
	); 			// apar greseli frecvent la ordinea firelor, la numarul lor, &lt;br /&gt;
*/				// mai ales daca modulul e complex si are multe intrari si intrari&lt;br /&gt;
 &lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Echivalent se pot folosi si &amp;quot;primitive&amp;quot; SystemVerilog pentru scrierea top-ului.&lt;br /&gt;
&lt;br /&gt;
Primitivele sunt porti logice care exista deja in limbaj, folosite atunci cand se doreste o descriere structurala a circuitului.&lt;br /&gt;
&lt;br /&gt;
In instantiere acestora, iesirea se pune prima, urmata de intrari.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; daca se doreste scrierea acestor porti de catre voi (ca mai sus), numele modulului nu trebuie sa fie un cuvant cheie ocupat de primitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v2&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
  &lt;br /&gt;
wire w0;&lt;br /&gt;
&lt;br /&gt;
and and_gate_0(w0,a,b);	// primitiva pentru poarta and&lt;br /&gt;
not not_gate_0(c,w0);  	// primitiva pentru poarta not&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fiind un modul simplu, intreaga functionalitate putea fi scrisa la nivel de &amp;quot;top&amp;quot; si simplificat ca mai jos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea alternativa a modulului top (fisierul top_v3.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module top_v3&lt;br /&gt;
    (&lt;br /&gt;
	    input logic a,&lt;br /&gt;
	    input logic b,&lt;br /&gt;
	    output logic c&lt;br /&gt;
    );&lt;br /&gt;
   &lt;br /&gt;
assign c = ~ (a &amp;amp; b); // a si b, negate&lt;br /&gt;
   &lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Testarea circuitul se face printr-un testbench, acesta fiind:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea testbench-ului (fisierul top_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module top_tb(); // din/in tb nu intra si iese nimic. niciodata.&lt;br /&gt;
&lt;br /&gt;
logic a_tb;	&lt;br /&gt;
logic b_tb;	&lt;br /&gt;
logic c_tb;	&lt;br /&gt;
&lt;br /&gt;
top dut	// instantierea modulului de tip &amp;quot;top&amp;quot; sub numele &amp;quot;dut&amp;quot; &lt;br /&gt;
	(&lt;br /&gt;
		.a(a_tb),&lt;br /&gt;
		.b(b_tb),&lt;br /&gt;
		.c(c_tb)&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin // in loc de { ... } din c/c++, in SystemVerilog se pune begin ... end &lt;br /&gt;
	#10;		// dupa 10 unitati de timp &lt;br /&gt;
	a_tb = 0;		// a_tb ia valoarea 0&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;		// dupa inca 10 unitati de timp, deci in total la 20&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 1;&lt;br /&gt;
	b_tb = 1;&lt;br /&gt;
	#10;&lt;br /&gt;
	a_tb = 0;&lt;br /&gt;
	b_tb = 0;&lt;br /&gt;
	&lt;br /&gt;
	#20 $stop();	// oprirea simularii &lt;br /&gt;
end //end pentru initial &lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Formele de unda rezultate din simulare se pot vedea mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:exemplu_rezolvat_nand_forme_de_unda.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In chenarul verde se pot observa instantele din simulare. &lt;br /&gt;
&lt;br /&gt;
Daca se doreste adaugarea de semnale noi pentru a fi vazute, se selecteaza modulul instantiat in care acestea se afla (chenar verde). &lt;br /&gt;
&lt;br /&gt;
Apoi, din chenarul rosu se aleg semnalele si se adauga prin click dreapta-&amp;gt;add to wave window. &lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara vizualizare, semnalele se pot grupa asa cum se vede in chenarul mov prin click dreapta-&amp;gt;new group.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se observa o functionare corecta circuitului, acesta fiind o poarta NAND. El scoate &amp;quot;0&amp;quot; cand ambele semnale de intrare sunt &amp;quot;1&amp;quot; si scoate &amp;quot;1&amp;quot; in rest.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea circuitului pe FPGA&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dupa ce circuitul a fost testat in simulare, se doreste punerea sa fizica pe placa FPGA. Pentru aceasta, se tine cont de urmatoarele.&lt;br /&gt;
&lt;br /&gt;
* Pentru a controla intrarile &amp;#039;&amp;#039;a&amp;#039;&amp;#039; si &amp;#039;&amp;#039;b&amp;#039;&amp;#039; ale circuitului &amp;#039;&amp;#039;&amp;#039;top&amp;#039;&amp;#039;, va trebui sa le conectam prin intermediul conexiunilor configurabile ale FPGA-ului la pini ce sunt mai departe conectati fizic la dispozitive ce pot controla valorile semnalelor (switch-uri, butoane).&lt;br /&gt;
* Pentru a observa valoarea iesirii, vom conecta semnalul de iesire &amp;#039;&amp;#039;c&amp;#039;&amp;#039;la un dispozitiv de observare, cum ar fi un LED, care va fi aprins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 1 si stins daca &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 0.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:NAND2 FPGA.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru a realiza conectarea porturilor modulului &amp;#039;&amp;#039;top&amp;#039;&amp;#039; la pinii fizici ai FPGA ce sunt conectati mai departe la componentele de pe placa, va trebui sa specificam in utilitarul de sinteza maparea porturilor la acestia. Maparea se realizeaza prin mentionarea codurilor pinilor la care dorim conexiunea si poata numele de &amp;#039;&amp;#039;&amp;#039;constrangeri de I/O&amp;#039;&amp;#039;&amp;#039;. Aceste coduri sunt mentionate in documentatia placii de dezvoltare cu FPGA (in cazul nostru, Boolean Board) si pot fi regasite si in pagina [[Boolean Board - Pinout]].&lt;br /&gt;
&lt;br /&gt;
Conform schemei, la acest exemplu avem nevoie de codurile pinilor conectati mai departe la Switch0, Switch1 si LED0.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Daca intrarile si iesirile ar fi semnale pe mai multi biti, fiecare bit al intrarilor va fi conectat la cate un switch/buton si fiecare bit al iesirii va fi conectat la un LED. Acest lucru este necesar deoarece switch-urile/butoanele pot avea doar doua stari (0 si 1) si astfel pot controla un singur bit. La fel, un LED poate avea doar doua stari (0 - stins si 1 - aprins) si poate afisa starea unui singur bit.&lt;br /&gt;
&lt;br /&gt;
Dupa ce ati extras codurile necesare, urmati pasii descrisi in [[Tutorial_Vivado|tutorialul Vivado]]. &lt;br /&gt;
&lt;br /&gt;
Dupa programarea cu succes a placii, puteti testa functionalitatea circuitului prin modficarea valorilor switch-urilor si observarea starii LED-ului.&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
Pentru urmatoarele exercitii se doreste atat testarea designurilor prin simulare cat si punerea acestora pe placa. Legat de placa, intrarile vor fi conectate la butoane, iar iesirile la leduri. Se va consulta tabelul cu pini disponibili ([[Boolean Board - Pinout]].).&lt;br /&gt;
&lt;br /&gt;
Exista moduri mai rapide de a scrie functionalitatea dorita (vezi exemplu), dar tema principala a acestui laborator este instantierea, asa ca sunteti rugati sa respectati desenele si sa instantiati fiecare poarta individual.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: AND4 din AND2=== &lt;br /&gt;
&lt;br /&gt;
Acest exercitiu arata cum se construieste o poarta AND cu 4 intrari din porti AND mai simple, cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca toate intrarile sunt &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_and4.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: OR4 din OR2===&lt;br /&gt;
&lt;br /&gt;
Asemanator cu exercitiul anterior, se poate construi si o poarta or cu 4 intrari din porti or cu 2 intrari. &lt;br /&gt;
Iesirea acesteia va fi &amp;quot;1&amp;quot; doar daca oricare din intrari (cel putin una) este &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_or4_din_or2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: AND4 din AND2 aranjat pe lung (nu arbore)===&lt;br /&gt;
&lt;br /&gt;
In multe cazuri, aceeasi functionalitate poate fi atinsa prin circuite care arata diferit. &lt;br /&gt;
O alta varianta de a face o poarta AND cu 4 intrari este prezentata mai jos. &lt;br /&gt;
&lt;br /&gt;
Comparati cele 2 variante. &lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_din_and2_v2.png ‎| 600px]]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: AND4 din NAND2===&lt;br /&gt;
&lt;br /&gt;
Orice poarta logica de baza poate fi construita doar din porti NAND sau doar din porti NOR. &lt;br /&gt;
&lt;br /&gt;
Desenati si implementati circuitul pentru o poarta AND4 din porti NAND cu 2 intrari. &lt;br /&gt;
&lt;br /&gt;
Tip: Incercati intai sa generati o poarta AND2 din NAND2.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului se folosesc formele de unda de la exercitiul 1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: AND4 pe 4b din AND4 pe 1b===&lt;br /&gt;
&lt;br /&gt;
Se pot face operatii logice si pe mai multi biti deodata prin punerea in paralel a mai multor porti cu o singura iesire.&lt;br /&gt;
	Exemplu :&lt;br /&gt;
		pentru intrarile 0011 si 1110 iesirea va fi 0010&lt;br /&gt;
&lt;br /&gt;
Pentru exersarea instantierii si intelegerea circuitului din spatele operatilor multibit implementati acest circuit prin instantierea a 4 porti AND2 pe 1 bit intr-o poarta AND2 pe 4 biti.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v1.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 5ns):&lt;br /&gt;
 &lt;br /&gt;
[[Fișier:Wavedrom_and4_4b.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
Exista si un mod mai rapid si simplu de a scrie aceasta functionalitate, grupand intrarile si iesirile in &amp;quot;bus&amp;quot;-uri, ca in codul de mai jos.&lt;br /&gt;
Acest mod de a grupa firele este desenat mai jos.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:schema_and4_4b_din_and4_1b_v2.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Fisierul and4_4b.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module and4_4b&lt;br /&gt;
	(&lt;br /&gt;
		input logic [3:0] in0,	// in0 are 4b, de la bit 3 la bit 0 inclusiv &lt;br /&gt;
		input logic [3:0] in1,	// se noteaza msb:lsb (most significant bit: least significant bit) (echivalent cu conceptul de cifra sutelor, cifra unitatilor, pt binar)&lt;br /&gt;
		input logic [3:0] in2,&lt;br /&gt;
		input logic [3:0] in3,&lt;br /&gt;
		output logic [3:0] out0&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
assign out0 = in0 &amp;amp; in1 &amp;amp; in2 &amp;amp; in3;&lt;br /&gt;
	&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Desenati schemele logice pentru urmatoarele circuite:===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;a) Schema 1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema1 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f, g;&lt;br /&gt;
	&lt;br /&gt;
	logic w1;&lt;br /&gt;
	logic w2;&lt;br /&gt;
	&lt;br /&gt;
	and P1 ( w1, a, c );&lt;br /&gt;
	or P2 ( f, w1, w2, d);&lt;br /&gt;
	not P3 (w2, b);&lt;br /&gt;
	and P4 (g, w1, b, d);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Observatie: In versiunea veche de verilog (si s-a pastrat si in cea curenta), se pot specifica directiile porturilor si in exteriorul parantezelor, ca mai sus. &lt;br /&gt;
Aceasta scriere NU este recomandata. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;b) Schema 2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module schema2 (a, b, c, d, f);&lt;br /&gt;
	input logic a, b, c, d;&lt;br /&gt;
	output logic f;&lt;br /&gt;
	&lt;br /&gt;
	logic w1, w2;&lt;br /&gt;
	&lt;br /&gt;
	nand P1 ( w1, a, b ), P2 (w2, c, d);&lt;br /&gt;
	and P3 ( f, w1, w2);&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; asemanator cu C/C++, se pot face declaratii in aceeasi linie a mai multor &amp;quot;variabile&amp;quot;, aici fire sau instante, cum se poate vedea la w1 si w2 (ambele fiind fire) sau la P1 si P2 (ambele fiind porti nand).&lt;br /&gt;
Aceasta scriere NU este recomandata.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_1_:_Generare_de_forme_de_unda&amp;diff=7931</id>
		<title>CID aplicatii 1 : Generare de forme de unda</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_1_:_Generare_de_forme_de_unda&amp;diff=7931"/>
		<updated>2025-02-23T20:35:05Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;În această sesiune de aplicații vom învăța cum să generăm semnale digitale cu ajutorul limbajului SystemVerilog. Generarea de semnale este utilizată în testarea prin simulare a circuitelor digitale. Semnalele generate sunt introduse la intrarea circuitului, observându-se apoi cum se modifică starea ieșirilor acestuia.&lt;br /&gt;
&lt;br /&gt;
Proiectarea circuitelor digitale se bazează pe generarea unor circuite digitale fizice. Deși se va scrie cod în limbajul SystemVerilog, mereu trebuie avut în vedere faptul că în spate se va genera un circuit fizic, codul nu se rulează pas cu pas, aceasta fiind deosebirea fundamentală dintre limbajele de descriere hardware (generează circuite fizice) și limbajele de programare (cod care se execută pas cu pas). Unele concepte cât și unele elemente de sintaxa este posibil să semene cu ce ați facut la programare, dar este important să  înțelegeți că prin codul scris se desenează/generează circuite. Sau invers, pornind de la un desen, se poate face o descriere în SystemVerilog a acestuia.&lt;br /&gt;
&lt;br /&gt;
Proiectele exemplu care pot fi descărcate au fost implementate folosind Vivado 2021.2. Dacă aveți altă versiune este posibil să vă ceară să le salvați în versiunea respectivă sau să fie nevoie să vă faceți un proiect nou, în care să adaugați fișierele cu cod.&lt;br /&gt;
&lt;br /&gt;
==Noțiuni și cunoștințe necesare==&lt;br /&gt;
 &lt;br /&gt;
* [[Introducere. SystemVerilog HDL]] (Sintaxa [[SystemVerilog]])&lt;br /&gt;
&lt;br /&gt;
* [[Tutorial Vivado]].&lt;br /&gt;
&lt;br /&gt;
==Modulul de test (Testbench)==&lt;br /&gt;
Modulul de test este un modul nesintetizabil (nu poate fi transformat într-un circuit de către utilitarul care realizează sinteza) și este folosit, așa cum sugerează și numele, în testarea circuitelor. Acest modul este folosit exclusiv în simulare. Simularea permite detecția rapidă a erorilor de implementare și corectarea acestora. Ideea generală a unui modul de test este descrisă în figura de mai jos (considerăm un circuit cu numele &amp;#039;&amp;#039;circuit&amp;#039;&amp;#039; și modulul său de test &amp;#039;&amp;#039;circuit_tb&amp;#039;&amp;#039;):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CircuitTestbench.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
După cum se vede în figura de mai sus, modulul de test conține printre altele și un &amp;#039;&amp;#039;&amp;#039;generator de semnale de test&amp;#039;&amp;#039;&amp;#039;. Acesta are rolul de a genera câte un semnal de test pentru fiecare intrare a circuitului. Forma acestor semnale de test este stabilită de către cel care realizează verificarea și trebuie aleasă astfel încât să detectăm cât mai multe posibile erori.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
====Exemplul 1: Generarea a doua semnale digitale de 1 bit====&lt;br /&gt;
Să se genereze două semnale digitale de 1 bit, care să aibă următoarea variație în timp (unitatea de timp este de 1ns):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CID Aplicatii1 ex1.svg|400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     // setăm unitatea de timp la 1ns, cu o precizie de 1ps&lt;br /&gt;
&lt;br /&gt;
module waveform1();    // modulul se numește waveform1 și nu are nicio intrare și nicio ieșire. Semnalele de test generate sunt semnale interne.&lt;br /&gt;
&lt;br /&gt;
logic a, b;              // cele două semnale de test sunt trebuie declarate ca elemente de tip logic.&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    $monitor(&amp;quot;time = %2d, a = %b, b=%b&amp;quot;, $time, a, b);  // monitorizăm în consolă starea semnalelor a si b&lt;br /&gt;
       a = 0;          // semnalul a va avea valoarea 0 la momentul inițial de timp (la momentul t = 0)&lt;br /&gt;
       b = 0;          // semnalul b va avea valoarea 0 la momentul inițial de timp (la momentul t = 0)&lt;br /&gt;
    #1 a = 1;          // după 1ns de la momentul inițial, a se face 1&lt;br /&gt;
    #1 b = 1;          // după 2ns de la momentul inițial, b se face 1&lt;br /&gt;
    #1 a = 0;          // după 3ns de la momentul inițial, a se face 0&lt;br /&gt;
       b = 0;          // după 3ns de la momentul inițial, b se face 0&lt;br /&gt;
    #2 $stop();        // simularea este oprită&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule              // incheiem descrierea modulului de generare de semnale digitale&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Atunci când un semnal are dimensiunea de 1 bit, nu va apărea nimic intre tipul acestuia și nume. Atunci când semnalul are o dimensiune mai mare sau egală cu doi biți, dimensiunea va fi descrisă sub forma &amp;#039;&amp;#039;&amp;#039;[n-1:0]&amp;#039;&amp;#039;&amp;#039;, unde &amp;#039;&amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;#039; este numărul de biți. Conform acestei descrieri, bitul &amp;#039;&amp;#039;&amp;#039;n-1&amp;#039;&amp;#039;&amp;#039; este cel mai semnificativ.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
logic a;           //semnal cu dimeniunea de 1 bit&lt;br /&gt;
logic [7:0] data;  //semnal/magistrală/bus cu dimensiunea de 8 biți&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Exemplul 2: Generarea unui semnal periodic de 1 bit====&lt;br /&gt;
Să se genereze un semnal digital periodic de 1 bit, cu perioada egală cu 2ns:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Clock wave.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     // setăm unitatea de timp la 1ns, cu o precizie de 1ps&lt;br /&gt;
&lt;br /&gt;
module waveform2();    // modulul se numește waveform2 si nu are nicio intrare și nicio iesire&lt;br /&gt;
&lt;br /&gt;
logic clock;             // semnalul de test este declarat de tip logic&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock = 0;                   // valoarea inițială a semnalului va fi 0 (la momentul t = 0)&lt;br /&gt;
    forever #1 clock = ~clock;   // forever indică faptul că ce urmează se va repeta într-o buclă continuă. &lt;br /&gt;
                                 // La trecea unui timp egal cu unitatea de timp definită, semnalul clock iși va nega valoarea&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    #20 $stop();       // La 20 de unități de timp (aici, 20 ns), simularea se va opri. &lt;br /&gt;
                       // Aici punem $stop într-un bloc separat, deoarece forever blochează blocul initial în care se află&lt;br /&gt;
                       // Toate blocurile initial încep la același moment de timp (t = 0) și au efect în paralel&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;
==Exerciții==&lt;br /&gt;
====Exercițiul 1====&lt;br /&gt;
Generați două semnale digitale &amp;#039;&amp;#039;&amp;#039;a&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;#039; de 1 bit, astfel încât să se formeze cu ele toate cele 4 combinații posibile, după cum urmează:&lt;br /&gt;
&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 0ns&amp;#039;&amp;#039;&amp;#039;: a = 0, b = 0&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 1ns&amp;#039;&amp;#039;&amp;#039;: a = 0, b = 1&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 2ns&amp;#039;&amp;#039;&amp;#039;: a = 1, b = 0&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;t = 3ns&amp;#039;&amp;#039;&amp;#039;: a = 1, b = 1&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 2====&lt;br /&gt;
Să se genereze un semnal digital de 8 biți aliniat la fronturile crescătoare ale unui semnal periodic (semnal de ceas), ce are perioada de 2ns:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Clock and data wave.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Frontul crescător al unui semnal este definit ca tranziția dintre nivelul de 0 logic și 1 logic.&lt;br /&gt;
* Spunem că un semnal este aliniat la fronturile crescătoare ale unui alt semnal dacă acesta își modifică valoarea imediat după apariția acelui front crescător. În figura de mai sus, se observă că &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; își schimbă valoarea imediat după fiecare front crescător al semnalului &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Indicații&amp;#039;&amp;#039;&amp;#039;: &lt;br /&gt;
&lt;br /&gt;
* Așteptarea unui front crescător al semnalului &amp;#039;&amp;#039;NumeSemnal&amp;#039;&amp;#039; se realizează cu &amp;#039;&amp;#039;&amp;#039;@(posedge &amp;#039;&amp;#039;NumeSemnal&amp;#039;&amp;#039;)&amp;#039;&amp;#039;&amp;#039;. Aceasta va înlocui întârzierile de tip &amp;#039;&amp;#039;&amp;#039;#n&amp;#039;&amp;#039;&amp;#039; folosite anterior.&lt;br /&gt;
* Pentru semnalele ce se doresc aliniate la un eveniment de tip &amp;#039;&amp;#039;&amp;#039;posedge&amp;#039;&amp;#039;&amp;#039;, vom folosi atribuirea non-blocantă: de exemplu, &amp;#039;&amp;#039;&amp;#039;data &amp;lt;= 1;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* Nu uitați! Folosirea &amp;#039;&amp;#039;forever&amp;#039;&amp;#039; pentru generarea semnalului de ceas va bloca acel bloc &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;.&lt;br /&gt;
* Incrementarea valorii unui semnal se poate realiza cu un bloc de tip &amp;#039;&amp;#039;for&amp;#039;&amp;#039;, inclus in blocul &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;. Blocul &amp;#039;&amp;#039;for&amp;#039;&amp;#039; va avea nevoie de un contor de tip &amp;#039;&amp;#039;integer&amp;#039;&amp;#039;, declarat în afara blocului &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;. Pentru mai multe detalii, consultați tutorialul de sintaxa SystemVerilog.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Folosind indicațiile anterioare, înlocuiți al doilea bloc &amp;#039;&amp;#039;initial&amp;#039;&amp;#039; din &amp;#039;&amp;#039;&amp;#039;Exemplul 2&amp;#039;&amp;#039;&amp;#039; cu următoarea secvență și completați liniile de cod lipsă:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
integer index;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    for(index = 0; index &amp;lt; 11; index = index + 1) begin&lt;br /&gt;
        //completati codul    &lt;br /&gt;
    end&lt;br /&gt;
    #20 $stop();&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Exercițiul 3====&lt;br /&gt;
Desenați formele de undă ale semnalelor de test &amp;#039;&amp;#039;a&amp;#039;&amp;#039;, &amp;#039;&amp;#039;b&amp;#039;&amp;#039; și &amp;#039;&amp;#039;c&amp;#039;&amp;#039;, generate cu ajutorul următoarelor două blocuri &amp;#039;&amp;#039;initial&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps     &lt;br /&gt;
&lt;br /&gt;
module waveform();    &lt;br /&gt;
&lt;br /&gt;
logic a, b, c; &lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       a = 0;          &lt;br /&gt;
       b = 0;          &lt;br /&gt;
    #2 b = 1;          &lt;br /&gt;
    #1 a = 1;          &lt;br /&gt;
    #3 b = 0;          &lt;br /&gt;
    #3 a = 0;          &lt;br /&gt;
    #2 $stop();       &lt;br /&gt;
end   &lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       c = 1;                   &lt;br /&gt;
    #2 c = 0;          &lt;br /&gt;
    #3 c = 1;                &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;
====Exercițiul 4====&lt;br /&gt;
Generati un semnal digital &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039; cu dimensiunea de 1 bit si perioada de 2ns si un semnal digital &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039;, cu dimensiunea de 4 biti, aliniat la fronturile crescatoare ale semnalului &amp;#039;&amp;#039;&amp;#039;clock&amp;#039;&amp;#039;&amp;#039;. Semnalul &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; va varia astfel: &amp;#039;&amp;#039;&amp;#039;0, 1, 2, 3, 0, 1, 2 ,3, 0, 1 ... &amp;#039;&amp;#039;&amp;#039;. Opriti simularea dupa ce semnalul &amp;#039;&amp;#039;&amp;#039;data&amp;#039;&amp;#039;&amp;#039; a realizat 4 variatii complete (s-a generat secventa &amp;#039;&amp;#039;&amp;#039;0, 1, 2, 3&amp;#039;&amp;#039;&amp;#039; de 4 ori).&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=7895</id>
		<title>CID aplicatii 5 : Exercitii cu circuite combinationale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=7895"/>
		<updated>2024-10-28T16:32:02Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostiintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 1 in anii anteriori si cateva notiuni de teorie si sintaxa ajutatoare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: Parametrizare==&lt;br /&gt;
Parametrizarea este un mod de a generaliza codul scris pentru a nu fi nevoie sa scrii acelasi modul de mai multe ori doar pentru ca circuitul isi schimba o dimensiune. &lt;br /&gt;
&lt;br /&gt;
Pentru a intelege mai clar avantajele si sintaxa urmariti urmatorul exemplu:&lt;br /&gt;
&lt;br /&gt;
Fisierul sumator.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator # // &amp;lt;= diez deoarece urmeaza lista cu paramteri&lt;br /&gt;
				( // parametri &lt;br /&gt;
					parameter data_size = 4 // valoare default 4&lt;br /&gt;
					// alti parametri aici daca este nevoie, separati prin virgula&lt;br /&gt;
				)&lt;br /&gt;
				( // interfata &lt;br /&gt;
					input logic [data_size-1:0] in0, // si pot folosii parametrul &amp;quot;data_size&amp;quot; pentru dimensiunea bus-ului&lt;br /&gt;
					input logic [data_size-1:0] in1,&lt;br /&gt;
					output logic [data_size-1:0] out0&lt;br /&gt;
				);&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 + in1;				&lt;br /&gt;
				&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cand se instantiaza un modul parametrizat, se specifica valorile parametrilor astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(8)   // se genereaza un sumator pe 8b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_0&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out0)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(32)  // se genereaza un sumator pe 32b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_1&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator nume_instanta_2 // se genereaza un sumator de dimensiune default, aici 4, asa cum e scris in modulul &amp;quot;sumator&amp;quot;&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out2)&lt;br /&gt;
	);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puteti folosi parametrizarea in exercitiul 3 de mai jos. Acolo sunt 2 tipuri de multiplexoare, unul cu intrarile pe 1 bit si unul cu intrarile pe 2 biti. Poate fi scris un singur modul parametrizat care sa acopere ambele situatii.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Concatenarea==&lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara conectare a firelor sau pentru o mai buna organizare si expresivitate a codului, de multe ori este util ca fire individuale sa fie grupate impreuna sau ca un bus de mai multi biti sa fie separat in fire individuale. Acest lucru se face folosind concatenarea, prin simbolurile &amp;quot;{ }&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Un exemplu de folosire a concatenarii este oferit mai jos.&lt;br /&gt;
Un sumator pe 8b are rezultatul pe maxim 9b, in cazul in care ambele numere sunt mari. Astfel apare un bit de carry out. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator ( &lt;br /&gt;
            input logic [7:0] in0,&lt;br /&gt;
            input logic [7:0] in1,&lt;br /&gt;
            output logic [7:0] out0,&lt;br /&gt;
            output logic carry_out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign {carry_out,out0} = in0 + in1; // fac suma intre in0 si in1 iar rezultatul il pun pe cei 9b alcatuiti din: 1b carry_out si 8b out0, in ordinea asta&lt;br /&gt;
&lt;br /&gt;
endmodule       &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Se pot concatena oricat de multe semnale, puse in &amp;quot;{ }&amp;quot; si separate prin virgula. Atentie la dimensiunile firelor care se concateneaza.&lt;br /&gt;
&lt;br /&gt;
Se poate de asemenea face concatenare si la dreapta egalului, astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fir_pe_10_b = {fir_pe_3b,fir_pe_5b,fir_pe_1b,fir_pe_1b};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In exemplul anterior ultimi 2b ai &amp;quot;fir_pe_10_b&amp;quot; vor avea mereu aceeasi valoare, provenind din acelasi fir. Sintaxa SystemVerilog permite asta.&lt;br /&gt;
&lt;br /&gt;
Puteti folosii concatenarea, in exercitiul 2, la flag-ul de overflow.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Constante ca intrari in circuite==&lt;br /&gt;
In cazul in care se doreste scrierea unor constante la intrarea unor module, acestea se pun direct intre paranteze la instantiere. &lt;br /&gt;
De exemplu, pentru multiplexorul de jos din subiectul &amp;quot;alu structural&amp;quot;, intrarea &amp;quot;in3&amp;quot; este conectata la valoarea &amp;quot;1&amp;quot;. Sintaxa pentru aceasta este: &amp;quot;.in3(1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: &amp;quot;_&amp;quot;==&lt;br /&gt;
Simbolul &amp;quot;_&amp;quot; (underscore) este ignorat de SystemVerilog si ajuta vizual la citirea semnalelor pe mai multi biti. De exemplu 16&amp;#039;b1010010111110000 este identic cu 16&amp;#039;b1010_0101_1111_0000, al doilea fiind totusi mai usor de citit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 0: Repararea erorilor===&lt;br /&gt;
Arhiva de mai jos contine mai multe proiecte in Vivado, fiecare avand cate o eroare de sintaxa sau de logica. In vederea aprofundari cunostiintelor voastre (si pentru lucrarea de saptamana urmatoare), incercati sa le parcurgeti si sa rezolvati toate problemele. &lt;br /&gt;
Pe langa proiecte in sine, in arhiva se afla si un fisier text cu o introducere, rezolvarile si explicatiile pentru fiecare situatie.&lt;br /&gt;
&lt;br /&gt;
[https://drive.google.com/file/d/1cNTpQC54_JEeSk8SxgHTEdGtobCn_-EI/view?usp=drive_link Arhiva_proiecte_cu_erori.zip]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: ALU - descriere comportamentala===&lt;br /&gt;
Descrieți comportamental o unitate aritmetico-logică (ALU) care are la intrare 2 numere binare de câte 8 biți și poate calcula următoarele funcții:&lt;br /&gt;
:- suma celor două numere&lt;br /&gt;
:- diferența celor două numere&lt;br /&gt;
:- operații logice bit cu bit (bitwise): SI, SAU, XOR și inversele lor&lt;br /&gt;
:- operandul din stanga trece neschimbat&lt;br /&gt;
:- operandul din dreapta trece neschimbat&lt;br /&gt;
:- numărul din stânga este deplasat la stânga cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
:- numărul din stânga este deplasat la dreapta cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
&lt;br /&gt;
Funcția executată la un anumit moment este determinată de configurația binară de pe intrarea de comandă (function).&lt;br /&gt;
&lt;br /&gt;
ALU are de asemenea intrare de carry și ieșire de carry, plus alte două ieșiri - indicatori - pentru cazurile când rezultatul este zero și când cei doi operanzi sunt egali.&lt;br /&gt;
&lt;br /&gt;
Intrarea de control va fi facuta pe 4 biti ca sa permita existenta a 16 operatii posibile. Fiecare numar de pe intrarea de control (combinatie de 0 si 1) va reprezenta o operatie din cele de mai sus. Scrierea se va face folosind un bloc &amp;quot;case&amp;quot; in functie de aceasta intrare. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: ALU - descriere structurala===&lt;br /&gt;
 &lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/8f/Subiect_big_alu.pdf subiect_alu.pdf]&lt;br /&gt;
	&lt;br /&gt;
Daca se doreste selectarea doar a anumitor biti dintr-un bus (cum se vrea din instruction) acest lucru se poate face in 2 feluri:&lt;br /&gt;
&lt;br /&gt;
a) cu fir aditional:&lt;br /&gt;
:&amp;#039;&amp;#039;wire [1:0] fir_aditional1;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;assign fir_aditional1 = instruction[11:10];&amp;#039;&amp;#039;&lt;br /&gt;
:// apoi la instantiere: &amp;#039;&amp;#039;.sel(fir_aditional1),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
b) direct in instantiere;&lt;br /&gt;
:la instantierea celor 2 mux4 din stanga, direct: &lt;br /&gt;
::&amp;#039;&amp;#039;.sel(instruction[11:10]),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie mai putin (a nu face toate modulele de calcul separat + instantierea lor) si pentru ca e vorba de operatii simple, se poate pune operatia cu assign direct in top pe un fir declarat acolo, sau si mai prescurtat, direct operatia dorita cand se intantiaza modulul in care aceasta intra. De exemplu, pentru operatia de shift la dreapta care intra in primul multiplexor, se poate pune:  &amp;quot;.in0(data0 &amp;gt;&amp;gt; data1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3:===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/3/3a/Subiect_muxes.pdf subiect_muxes.pdf]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4:===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2e/Subiect_rom_luts.pdf rom_luts.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Sumator cu reprezentare in cifre zecimale===&lt;br /&gt;
Proiectati si verificati un sumator zecimal pentru numere cu 2 cifre&lt;br /&gt;
&lt;br /&gt;
Modulul de top (Figura 1) este alcatuit din 2 blocuri de tip &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;. Fiecare bloc aduna cifrele de pe aceasi pozitie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 1&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
   Top level&lt;br /&gt;
&lt;br /&gt;
[[Fișier: bcdsum.png]]&lt;br /&gt;
&lt;br /&gt;
Blocul &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; (Figura 2) este alctuit din 4 blocuri, 2 sumatoare binare pe 4 biti (de tip &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039;), o instanta de &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039; si un multiplexor elementar mux2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 2&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
   Blocul DIGIT SUM &lt;br /&gt;
&lt;br /&gt;
[[Fișier: digit.png]]&lt;br /&gt;
&lt;br /&gt;
Primul sumator aduna cifrele din domeniul [0...9] avand un rezultat intre [0 ... 18] &lt;br /&gt;
&lt;br /&gt;
Comparatorul are la iesire 1 daca rezultatul este mai mare decat 9.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mic decat 9, acesta este trimis in mod direct la iesirea &amp;#039;&amp;#039;&amp;#039;digit&amp;#039;&amp;#039;&amp;#039; a blocului &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mare decat 9, o crectie este necesara si se aduna 6 la rezultat.&lt;br /&gt;
&lt;br /&gt;
Comparatorul cu valoarea 9 este descris structural din porti in figura de mai jos: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 3&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
   the comparator &lt;br /&gt;
&lt;br /&gt;
[[Fișier: cmp.png]]&lt;br /&gt;
&lt;br /&gt;
Testbench-ul va genera stimuli pentru &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
Intrarea b0 a &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; se schimba la fiecare 5 pasi de simulare .&lt;br /&gt;
&lt;br /&gt;
b1, a0 si a1 se schimba sincron cu b0 ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: teststimuli.png]]&lt;br /&gt;
&lt;br /&gt;
Cerinte:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039;- descris structural la nivel de porti ca in Figura 3.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039; descris comportamental cu un assign continuu.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;mux&amp;#039;&amp;#039;&amp;#039; descris comportamental cu always.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; descris strctural ca in Figura 2.&lt;br /&gt;
# modulul de top numit &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039;, descris structural ca in Figure 1.&lt;br /&gt;
# modulul de testbench, &amp;#039;&amp;#039;&amp;#039;bcdsum_tb&amp;#039;&amp;#039;&amp;#039;, instantiaza &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; cu numele &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# in testbench, generati stimuli pentru intrarile circuitului testat.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_7_:_Circuite_secventiale_elementare&amp;diff=7894</id>
		<title>CID aplicatii 7 : Circuite secventiale elementare</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_7_:_Circuite_secventiale_elementare&amp;diff=7894"/>
		<updated>2024-10-22T13:57:40Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Hazardul combinațional== &lt;br /&gt;
&lt;br /&gt;
Hazardul apare atunci când modificarea unei intrări a unui circuit combinațional determină modificări nedorite ale ieșirii. Aceste variații apar datorită diferențelor de întârzieri pe diverse căi de la intrare către ieșire.&lt;br /&gt;
&lt;br /&gt;
De unde aceste întârzieri? Fiecare poartă este, așa cum am văzut la începutul aplicațiilor, un circuit electronic format, de obicei, din tranzistoare MOS. Răspunsul acestor dispozitive nu este instantaneu, introducând întârzieri. Timpul scurs de la modificarea unei intrări a unei porți până la modificarea corespunzătoare a ieșirii se numește timp de propagare.&lt;br /&gt;
&lt;br /&gt;
În figura următoare avem evidențiat timpul de propagare printr-o poartă &amp;#039;&amp;#039;SAU&amp;#039;&amp;#039; (Tp). Acesta este reprezentat de timpul scurs de la modificarea lui a până la modificarea ieșirii.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Comutare poarta SAU.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
Avănd un circuit cu mai multe porți în cascadă, căile prin care anumite semnale ajung la intrările unei anumite porți pot diferi. Datorită timpilor de propagare diferiți care afectează aceste semnale până să ajungă la poarta curentă și a timpului de propagare efectiv al porții curente, pot apărea la ieșire tranziții nedorite ale semnalelor. Dacă la ieșire se așteaptă ca linia să rămană constant în 1, dar apare o scurtă tranziție prin 0, hazardul se numește &amp;#039;&amp;#039;1 static&amp;#039;&amp;#039;. Dacă la ieșire se așteaptă ca linia să rămană constant în 0, dar apare o scurtă tranziție prin 1, hazardul se numește &amp;#039;&amp;#039;0 static&amp;#039;&amp;#039;. Dacă se așteaptă o tranziție la ieșire, dar apare un regim tranzitoriu cu numeroase tranziții până la stabilizare, hazardul se numește dinamic.&lt;br /&gt;
&lt;br /&gt;
Pentru a înțelege mai bine, să considerăm exemplul de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Circuit comb hazard.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
Observăm că intrările porții &amp;#039;&amp;#039;P2&amp;#039;&amp;#039; urmează căi diferite: semnalul &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este ieșirea unei porți, având o întârziere cauzată de timpul de propagare al porții &amp;#039;&amp;#039;P1&amp;#039;&amp;#039;, pe când semnalul &amp;#039;&amp;#039;b&amp;#039;&amp;#039; vine direct de la intrare, propagarea prin fir fiind neglijabilă. Să considerăm cazul în care intrarea &amp;#039;&amp;#039;a&amp;#039;&amp;#039; rămane permanent în 0, iar intrarea &amp;#039;&amp;#039;b&amp;#039;&amp;#039; comută la un moment dat din 0 în 1. Inițial, semnalul &amp;#039;&amp;#039;c&amp;#039;&amp;#039; este 1, iar &amp;#039;&amp;#039;d&amp;#039;&amp;#039; este 1. După comutarea lui &amp;#039;&amp;#039;b&amp;#039;&amp;#039;, semnalul &amp;#039;&amp;#039;c&amp;#039;&amp;#039; va comuta din 1 in 0, iar &amp;#039;&amp;#039;d&amp;#039;&amp;#039; va rămane 1. Acesta este cazul ideal. În realitate, datorită timpilor de propagare ai porților logice &amp;#039;&amp;#039;P1&amp;#039;&amp;#039; și &amp;#039;&amp;#039;P2&amp;#039;&amp;#039;, vom avea o scurtă tranziție prin 0:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Circuit comb hazard propagare.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Atribuirea blocanta si non-blocanta==&lt;br /&gt;
Pentru ca simulatorul sa functioneze in mod corect si semnalele sa se modifice in simulare asa cum se modifica si in realitate este nevoie sa folosim atribuirea blocanta ( semnul &amp;quot;=&amp;quot;) la circuite combinationale si atribuirea non-blocanta (semnul &amp;quot;&amp;lt;=&amp;quot;) la circuite secventiale. &lt;br /&gt;
&lt;br /&gt;
In mod uzual orice always combinational ( &amp;#039;&amp;#039;&amp;#039;always@(*)&amp;#039;&amp;#039;&amp;#039; ) va folosi &amp;#039;&amp;#039;&amp;#039;atribuirea blocanta ( = )&amp;#039;&amp;#039;&amp;#039; si orice always pe ceas ( &amp;#039;&amp;#039;&amp;#039;always@(posedge clock)&amp;#039;&amp;#039;&amp;#039; ) va folosi &amp;#039;&amp;#039;&amp;#039;atribuirea non-blocanta ( &amp;lt;= )&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Diferenta dintre cele 2 atribuiri consta in modul in care simulatorul &amp;quot;executa&amp;quot; instructiunea de atribuire. La atribuirea blocanta se simuleaza linie cu linie, in ordinea in care acestea au fost scrise. La atribuirea non-blocanta se salveaza toti termenii din dreapta si se pun deodata (in acelasi pas de simulare) in termenii din stanga. Pentru a clarifica acest concept avem exemplul de mai jos: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
a = b;&lt;br /&gt;
b = a;&lt;br /&gt;
&lt;br /&gt;
c &amp;lt;= d;&lt;br /&gt;
d &amp;lt;= c;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In primul caz, deoarece am folosit atribuirea blocanta, a ia valoarea lui b si apoi b ia valoarea lui a, care deja a devenit b deci concret b ramane pe loc si deci atat a cat si b vor avea aceasi valoare la final.&lt;br /&gt;
&lt;br /&gt;
In al doilea caz, deoarece am folosit atribuirea non-blocanta, ce este in partea dreapta se transfera peste operanzii din stanga deodata, astfel c ia valoarea lui d si d ia valoarea lui c, la final avand loc o interschimbare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Latch-ul==&lt;br /&gt;
Latch-urile sunt dispozitive elementare de memorare, sensibile la nivelul semnalelor de intrare. Exemple de astfel de dispozitive sunt latch-urile de tip SR și latch-urile de tip D.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Latch-ul SR===&lt;br /&gt;
Latch-ul de tip SR poate fi realizat cu două porți &amp;#039;&amp;#039;SI NU&amp;#039;&amp;#039; sau &amp;#039;&amp;#039;SAU NU&amp;#039;&amp;#039; și este un dispozitiv asincron controlat de stările semnalelor &amp;#039;&amp;#039;S&amp;#039;&amp;#039; (set) și &amp;#039;&amp;#039;R&amp;#039;&amp;#039; (reset). Tabelul de adevăr al acestui circuit este prezentat mai jos. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Latch SR.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Atunci când &amp;#039;&amp;#039;S&amp;#039;&amp;#039; este 1 și &amp;#039;&amp;#039;R&amp;#039;&amp;#039; este 0, ieșirea &amp;#039;&amp;#039;Q&amp;#039;&amp;#039; va deveni 1, iar &amp;#039;&amp;#039;Qn&amp;#039;&amp;#039; va deveni 0. Atunci când &amp;#039;&amp;#039;R&amp;#039;&amp;#039; este 1 și &amp;#039;&amp;#039;S&amp;#039;&amp;#039; este 0, ieșirea &amp;#039;&amp;#039;Q&amp;#039;&amp;#039; se resetează (devine 0), iar &amp;#039;&amp;#039;Qn&amp;#039;&amp;#039; devine 1. Starea de memorare apare atunci când atât &amp;#039;&amp;#039;R&amp;#039;&amp;#039; cât și &amp;#039;&amp;#039;S&amp;#039;&amp;#039; sunt 0 în același timp. Cazul în care &amp;#039;&amp;#039;R&amp;#039;&amp;#039; și &amp;#039;&amp;#039;S&amp;#039;&amp;#039; sunt 1 în același timp duce la un comportament nedorit. (atât &amp;#039;&amp;#039;Q&amp;#039;&amp;#039; cât și &amp;#039;&amp;#039;Qn&amp;#039;&amp;#039; vor fi 0, ceea ce este incorect din punct de vedere al logicii dorite – &amp;#039;&amp;#039;Qn&amp;#039;&amp;#039; să fie negatul lui &amp;#039;&amp;#039;Q&amp;#039;&amp;#039;). În plus, dacă din aceasta stare se dorește trecerea în starea de memorare (&amp;#039;&amp;#039;R&amp;#039;&amp;#039; = 0, &amp;#039;&amp;#039;S&amp;#039;&amp;#039; = 0), poate apărea oscilația. În realitate, cele două porți nu vor avea același timp de propagare datorită variațiilor de producție și circuitul va ajunge în cele din urma într-o stare stabilă, nepredictibilă.&lt;br /&gt;
&lt;br /&gt;
===Latch-ul de tip D===&lt;br /&gt;
Latch-ul de tip D elimină problema combinațiilor nedorite de la ieșire. Acesta modifică ieșire doar atunci când semnalul de enable (&amp;#039;&amp;#039;E&amp;#039;&amp;#039;) este 1. Altfel, atunci când &amp;#039;&amp;#039;E&amp;#039;&amp;#039; este 0, va memora starea anterioara (&amp;#039;&amp;#039;Qt-1&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Latch D.png|500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Bistabilul de tip D==&lt;br /&gt;
Bistabilul de tip D este un dispozitiv de memorare ce salvează valoarea intrării pe unul din fronturile ceasului (în mod uzual, frontul crescător). El poate fi obținut prin conectarea a două latch-uri de tip D, conform schemei de mai jos. De obicei, singura ieșire care ne interesează este &amp;#039;&amp;#039;Q&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Bistabil D.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Comportamentul bistabilului de tip D poate fi observat în forma de undă următoare. Modificările lui &amp;#039;&amp;#039;data_out&amp;#039;&amp;#039; sunt determinate de fronturile crescătoare ale semnalului &amp;#039;&amp;#039;clock&amp;#039;&amp;#039;. La apariția acestora, &amp;#039;&amp;#039;data_out&amp;#039;&amp;#039; va lua valoarea intrării &amp;#039;&amp;#039;data_in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Forma unda bistabil.png]]&lt;br /&gt;
&lt;br /&gt;
===Bistabilul de tip D cu reset sincron===&lt;br /&gt;
Resetarea unui bistabil înseamnă aducerea valorii memorate la 0 sau la o altă valoare de reset definită de cel care proiectează circuitul. Vom considera în exemplul nostru că semnalul de &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; va fi activ în 0 și va face 0 valoarea memorată atunci când este activ. Un reset sincron înseamnă că acesta va acționa asupra valorii memorate&amp;#039;&amp;#039;data_out&amp;#039;&amp;#039; pe frontul crescător al ceasului.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Forma unda bistabil reset sincron.png]]&lt;br /&gt;
&lt;br /&gt;
===Bistabilul de tip D cu reset asincron===&lt;br /&gt;
Un reset asincron înseamnă că acesta va acționa asincron, fără a ține cont de ceas. Acest lucru înseamnă că el va acționa asupra valorii memorate imediat ce devine activ. În exemplele noastre, vom considera semnalul de &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; ca fiind activ în 0. Trecerea sa în 0 (frontul căzător) determină imediat resetarea circuitului. De asemenea, orice eveniment de front crescător de ceas ce apare cât timp reset-ul este activ, va duce la menținerea resetării circuitului. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Forma unda bistabil reset asincron.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
===Exemplul 1: Evidențierea hazardului combinațional===&lt;br /&gt;
&lt;br /&gt;
Implementați circuitul cu porți logice prezentat în secțiunea de introducere teoretică și reproduceți în modulul de testare variațiile semnalelor &amp;#039;&amp;#039;a&amp;#039;&amp;#039; și &amp;#039;&amp;#039;b&amp;#039;&amp;#039; propuse, astfel încât să observăm pe ieșirea &amp;#039;&amp;#039;d&amp;#039;&amp;#039; hazardul.&lt;br /&gt;
&lt;br /&gt;
Deoarece în simulare propagarea este ideală, va trebui să introducem un timp de propagare folosind &amp;#039;&amp;#039;#n&amp;#039;&amp;#039;. Acesta va avea efect doar în simulare și va fi ignorat la o eventuală sinteză.&lt;br /&gt;
&lt;br /&gt;
Pentru modulul de test, va trebui să alegem un timp de modificare a valorilor semnalelor mai mare decât timpul de propagare ales. Aici, vom folosi 1ns timp de propagare și 5ns timp de variație a intrărilor in testbench.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea SystemVerilog a circuitului&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;
`timescale 1ns/1ps&lt;br /&gt;
module Circuit(&lt;br /&gt;
    input logic a,&lt;br /&gt;
    input logic b,&lt;br /&gt;
    output logic c,&lt;br /&gt;
    output logic d&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
assign #1 c = ~(a | b);&lt;br /&gt;
assign #1 d = ~(c &amp;amp; b);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test care să evidențieze hazardul&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps&lt;br /&gt;
&lt;br /&gt;
module Circuit_TB();&lt;br /&gt;
&lt;br /&gt;
logic a_t, b_t;&lt;br /&gt;
logic c_t, d_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       a_t = 0;&lt;br /&gt;
       b_t = 0;&lt;br /&gt;
    #5 b_t = 1;&lt;br /&gt;
    #5 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
Circuit DUT(&lt;br /&gt;
    .a(a_t),&lt;br /&gt;
    .b(b_t),&lt;br /&gt;
    .c(c_t),&lt;br /&gt;
    .d(d_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Poza_hazard.png ‎| 800px]]&lt;br /&gt;
&lt;br /&gt;
In acest exemplu se observa ca iesirea c se modifica la 1ns dupa modificarile intrarilor (intarizerea adaugata pentru transmiterea prin porti) si iesirea d se modifica de 2 ori: prima data la 1ns din cauza intrarilor si a doua oara dupa inca 1ns din cauza lui c. In intervalul [6-7]ns apare o valoare parazita, un hazard.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Descrierea comportamentală a latch-ului de tip D===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea SystemVerilog a modulului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module latch_D(&lt;br /&gt;
    input logic D,&lt;br /&gt;
    input logic E,&lt;br /&gt;
    output logic Q&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
assign Q = (E == 1) ? D : Q;&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Modul de test pentru latch-ul D&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps&lt;br /&gt;
&lt;br /&gt;
module latch_D_TB();&lt;br /&gt;
&lt;br /&gt;
logic D_t, E_t;&lt;br /&gt;
logic Q_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       D_t = 0;&lt;br /&gt;
       E_t = 1;&lt;br /&gt;
    #1 D_t = 1;&lt;br /&gt;
    #1 D_t = 0;&lt;br /&gt;
    #1 E_t = 0;&lt;br /&gt;
    #1 D_t = 1;&lt;br /&gt;
    #1 D_t = 0;&lt;br /&gt;
    #5 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
latch_D DUT1(&lt;br /&gt;
    .D(D_t),&lt;br /&gt;
    .E(E_t),&lt;br /&gt;
    .Q(Q_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exemplul 3: Descrierea comportamentală a bistabilului de tip D===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea SystemVerilog a modulului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module flipflop_D(&lt;br /&gt;
    input logic data_in,&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    output logic data_out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    data_out &amp;lt;= data_in; // atribuire non-blocanta&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;
&amp;#039;&amp;#039;&amp;#039;Modulul de test pentru bistabilul de tip D&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps&lt;br /&gt;
&lt;br /&gt;
module flipflop_D_TB();&lt;br /&gt;
&lt;br /&gt;
logic data_in_t, clock_t;&lt;br /&gt;
logic data_out_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
       data_in_t = 0;&lt;br /&gt;
    #2 data_in_t = 1;&lt;br /&gt;
    #4 data_in_t = 0;&lt;br /&gt;
    #5 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~ clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
flipflop_D DUT(&lt;br /&gt;
    .data_in(data_in_t),&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .data_out(data_out_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Atunci cand avem un circuit secvential, se foloseste atribuirea non-blocanta (&amp;quot;&amp;lt;=”)&lt;br /&gt;
&lt;br /&gt;
==Exerciții==&lt;br /&gt;
===Exercițiul 1===&lt;br /&gt;
Descrieți structural latch-ul de tip SR, conform schemei din secțiunea de introducere teoretică. Puteți simula întârzierile prin porți folosind #1.&lt;br /&gt;
&lt;br /&gt;
Realizați un modul de test care să pună în evidență funcționarea. Respectați la generarea stimulilor următoarea variație (fiecare segment de timp durează 5ns).&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Forma unda latchSR.png]]&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 2===&lt;br /&gt;
Modificați descrierea bistabilului de tip D prezentată în exemple, astfel încât acesta să permită resetarea sincronă. Semnalul de reset va fi activ în 0.&lt;br /&gt;
&lt;br /&gt;
Realizați un modul de test care să respecte la generarea stimulilor forma de unda prezentată în secțiunea de introducere teoretică, la &amp;#039;&amp;#039;&amp;#039;Bistabilul de tip D cu reset sincron&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 3===&lt;br /&gt;
Modificați descrierea bistabilului de tip D prezentată în exemple, astfel încât acesta să permită resetarea asincronă. Semnalul de reset va fi activ în 0.&lt;br /&gt;
&lt;br /&gt;
Realizați un modul de test care să respecte la generarea stimulilor forma de unda prezentată în secțiunea de introducere teoretică, la &amp;#039;&amp;#039;&amp;#039;Bistabilul de tip D cu reset asincron&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Indicație&amp;#039;&amp;#039;&amp;#039;: Frontul căzător al semnalului &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; va trebui să fie adăugat în lista de sensitivități a blocului always care determină modificarea lui &amp;#039;&amp;#039;data_out&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 4===&lt;br /&gt;
Pentru evidentierea hazardului combinational (si a modului in care acesta se rezolva) descrieti in SystemVerilog si simulati urmatoarele 2 circuite:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Poza_circ_secventiale_basic_exercitiu_4_circuit.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
Pentru a putea observa efectele hazardului, portile trebuie descrise ca avand timpi de propagare.&lt;br /&gt;
&lt;br /&gt;
Formele de unda pentru semnalele de la intrare vor fi:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Poza_circ_secventiale_basic_exercitiu_4_forme_unda.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 5===&lt;br /&gt;
Pentru evidentierea efectului atribuirii blocant si non-blocante se va implementa si simula circuitul de mai jos. El este alcatuit din 3 registre, fiecare memorand (si punand la iesire) pe frontul pozitiv al ceasului valoarea de la intrare.&lt;br /&gt;
&lt;br /&gt;
Cele 3 registre de sus vor folosii atribuirea blocanta si cele 3 registre de jos vor folosii atribuirea non-blocanta. In simulare se doreste a se vizualiza: intrarile, iesirile, firele interne de legatura dintre registrii.&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie semnificativ mai putin, nu este nevoie sa instantiati fiecare registru dintro serie ca modul separat ci se pot face toate cele 3 atribuiri in cadrul aceluiasi bloc &amp;quot;always&amp;quot;, la nivelul de top. Practic tot circuitul se reduce la un fisier de top ce contine intrari/iesiri, declararea registrilor pe 1b si cele 2 always-uri care dicteaza functionarea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Poza_circ_secventiale_basic_exercitiu_5_circuit.png ‎| 600px]]&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_8_:_Registre_si_memorii_RAM&amp;diff=7893</id>
		<title>CID aplicatii 8 : Registre si memorii RAM</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_8_:_Registre_si_memorii_RAM&amp;diff=7893"/>
		<updated>2024-10-22T13:57:28Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are scopul de a prezenta circuitele secventiale simple: registre si memorii RAM. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pornind de la bistabilii prezentati/construiti in laboratorul anterior, apare notiunea de registru, acesta fiind o grupare de bistabili. Astfel in loc sa se memoreze un singur bit de informatie (bistabil), se pot memora acum numere pe mai multi biti (registru).&lt;br /&gt;
&lt;br /&gt;
Din exterior, un registru este vazut astfel: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Registru_exterior_view.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Semnalul de &amp;quot;clock&amp;quot; controleaza sincronizarea registrilor din tot sistemul.&lt;br /&gt;
:Semnalul de &amp;quot;reset&amp;quot; aduce registrul la o valoare initiala (uzual 0).&lt;br /&gt;
:Semnalul de &amp;quot;we&amp;quot; (write enable) controleaza salvarea unor date noi. Cand acesta este activ, data de pe intrarea &amp;quot;data_in&amp;quot; se salveaza in registru.&lt;br /&gt;
:Semnalul &amp;quot;data_in&amp;quot; reprezinta datele ce se doresc a fi scrise in registru.&lt;br /&gt;
:Semnalul &amp;quot;data_out&amp;quot; reprezinta valoarea stocata in registru.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Semnalele &amp;quot;data_in&amp;quot; si &amp;quot;data_out&amp;quot; pot fi pe oricat de multi biti se doreste, in mod uzual multipli de 8.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pornind de la notiunea de registru (care poate fi vazut ca o memorie cu o locatie si avand &amp;quot;m&amp;quot; biti) se doreste cresterea acestei memorii astfel incat aceasta sa curpinda mai multe locatii adresabile, unde se pot stoca date. Adaugand mai multi registri in paralel, unul langa altul, si cateva circuite de tip mux/demux se poate obtine o memorie de tip RAM (Random Access Memory), cu &amp;quot;m&amp;quot; locatii de &amp;quot;n&amp;quot; biti fiecare. Aceste memorii se cheama &amp;quot;Random Access&amp;quot; deoarece permit si scriere si citire. In functie de tehologia folosita, memoriile RAM pot fi construite din bistabili sau din latch-uri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Din exterior, o memorie RAM este vazuta astfel: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Ram_mXn_1read_1write_exterior_view.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Semnalele acestui circuit se pot imparti in semnale ce tin de interfata de scriere sau interfata de citire si mai apoi in semnale de date si semnale de control. Interfata sa este: &lt;br /&gt;
	&lt;br /&gt;
:Semnalul de &amp;quot;clock&amp;quot;: controleaza sincronizarea registrilor din memorie.&lt;br /&gt;
:Semnalul &amp;quot;addr_read&amp;quot;: adresa de la care se citesc datele. &lt;br /&gt;
:Semnalul &amp;quot;data_read&amp;quot;: data ce se citeste.&lt;br /&gt;
:Semnalul de &amp;quot;we&amp;quot;: semnal de control ce controleaza activarea scrierii. Scrierea are loc doar cand acest semnal este activ.&lt;br /&gt;
:Semnalul &amp;quot;addr_write&amp;quot;: adresa la care se scriu datele.&lt;br /&gt;
:Semnalul &amp;quot;data_write&amp;quot;: data ce urmeaza a fi scrisa atunci cand semnalul &amp;quot;we&amp;quot; este activ.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Orice memorie are &amp;quot;m&amp;quot; locatii de &amp;quot;n&amp;quot; biti. Semnalele de &amp;quot;data_read&amp;quot; si &amp;quot;data_write&amp;quot; au aceeasi dimensiune, &amp;quot;n&amp;quot;, numarul de biti ai fiecarei locatii. Semnalele de adresa au dimensiunea log2(m). Pentru o memorie cu 16 locatii va fi nevoie de 4 biti de adresa pentru a putea selecta orice locatie, pentru 32 locatii 5b s.a.m.d. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: In unele situatii se mai poate pune un registru suplimentar pe iesirea datelor, cu rol in sincronizare si evitarea timpilor de propagare prea lungi intre elemente de memorare (ajuta implementarea conceptului de pipeline).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Exista mai multe variante de memorii RAM (cu registru pe iesire/fara, multiport/single port citire, adrese separate sau nu pentru citire/scriere). Cea de mai sus este o memorie cu un singur port de citire, fara registru suplimentar pe iesire, ce foloseste adrese distincte pentru citire si pentru scriere (la fel de bine se poate lucra si cu o singura adresa, comuna pentru scriere si citire).&lt;br /&gt;
 &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Memoriile RAM pot sa nu aiba reset, utilizatorul trebuie apoi sa aiba grija sa citeasca doar din locatii scrise de el anterior.&lt;br /&gt;
In mod uzual ele nu au reset.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
&lt;br /&gt;
===Exemplul 1 : Registrul===&lt;br /&gt;
&lt;br /&gt;
In urmatorul exemplu se implementeaza registrul descris mai sus:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea registrului (fisierul register_8b.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module register_8b&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset, // activ pe &amp;quot;1&amp;quot;&lt;br /&gt;
		input logic we,&lt;br /&gt;
		input logic [7:0] data_in, &lt;br /&gt;
		output logic [7:0] data_out // data_out are aceeasi dimensiune ca data_in&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
always_ff @(posedge clock) // clock sincronizeaza actiunile circuitului&lt;br /&gt;
begin    // doar pe edge-ul pozitiv circuitul actioneaza&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
    	begin&lt;br /&gt;
    	data_out &amp;lt;= 0;&lt;br /&gt;
    	end&lt;br /&gt;
    else&lt;br /&gt;
    	begin&lt;br /&gt;
		if(we == 1) // comanda de scriere&lt;br /&gt;
			begin&lt;br /&gt;
			data_out &amp;lt;= data_in;&lt;br /&gt;
			end&lt;br /&gt;
		else // puteam sa omit acest else&lt;br /&gt;
			begin&lt;br /&gt;
			data_out &amp;lt;= data_out; // raman datele salvate anterior&lt;br /&gt;
			end&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;
&lt;br /&gt;
Un alt mod de a scrie un registru este dat mai jos, cu observatia ca aici am pus semnalul de reset activ in logica negativa:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea registrului (fisierul register_8b_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module register_8b_v2&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset_n, // activ in &amp;quot;0&amp;quot;&lt;br /&gt;
		// uzual semnalel cu n in fata sau la sfarsit sunt in logica negativa: nreset, resetn&lt;br /&gt;
		input logic we,&lt;br /&gt;
		input logic [7:0] data_in,&lt;br /&gt;
		output logic [7:0] data_out&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
logic [7:0] memorie_efectiva;   &lt;br /&gt;
&lt;br /&gt;
assign data_out = memorie_efectiva;&lt;br /&gt;
    &lt;br /&gt;
always_ff @(posedge clock)&lt;br /&gt;
begin  &lt;br /&gt;
	if( reset_n == 0) &lt;br /&gt;
		begin&lt;br /&gt;
		memorie_efectiva &amp;lt;= 0;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		begin&lt;br /&gt;
		if(we == 1)&lt;br /&gt;
			begin&lt;br /&gt;
			memorie_efectiva &amp;lt;= data_in;&lt;br /&gt;
			end&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;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea test bench-ului registrului pe 8biti: (fisierul register_8b_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module register_8b_tb();&lt;br /&gt;
&lt;br /&gt;
logic clock_tb;&lt;br /&gt;
logic reset_tb;&lt;br /&gt;
logic we_tb;&lt;br /&gt;
logic [7:0] data_in_tb;&lt;br /&gt;
logic [7:0] data_out_tb;&lt;br /&gt;
&lt;br /&gt;
register_8b dut 	// varianta cu reset activ in &amp;quot;1&amp;quot;&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock_tb),&lt;br /&gt;
		.reset(reset_tb),&lt;br /&gt;
		.we(we_tb),&lt;br /&gt;
		.data_in(data_in_tb),&lt;br /&gt;
		.data_out(data_out_tb)&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	clock_tb = 0;&lt;br /&gt;
	forever &lt;br /&gt;
		begin&lt;br /&gt;
		#5 clock_tb = ~clock_tb; // perioada totala 10 !!!&lt;br /&gt;
		end&lt;br /&gt;
end    &lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	reset_tb &amp;lt;= 0;&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	data_in_tb &amp;lt;= 0;&lt;br /&gt;
		// observatie: pana la primul reset sau prima scriere, valoarea din registru va fi necunoscuta (in simulare X)&lt;br /&gt;
		&lt;br /&gt;
		// dau reset la circuit&lt;br /&gt;
	@(posedge clock_tb); // astept sa treaca 1 clock cycle&lt;br /&gt;
	reset_tb &amp;lt;= 1;	&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	reset_tb &amp;lt;= 0;&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		// incep sa fac scrieri&lt;br /&gt;
	we_tb &amp;lt;= 1;&lt;br /&gt;
	data_in_tb &amp;lt;= 5;&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	data_in_tb &amp;lt;= 10;	// scrierea asta nu se face deoarece nu am write enable activ&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_in_tb &amp;lt;= 11;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_in_tb &amp;lt;= 12;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb = 1;&lt;br /&gt;
	data_in_tb &amp;lt;= 42;	// asta da&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_in_tb &amp;lt;= 51;	// si asta da&lt;br /&gt;
	@(posedge clock_tb);	&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&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;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Memorie RAM===&lt;br /&gt;
	&lt;br /&gt;
In urmatorul exemplu se implementeaza memoria RAM descrisa mai sus, particularizata pentru 64 de locatii a cate 8b fiecare:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea memoriei RAM: (fisierul ram64x8_v1.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module ram64x8_v1&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		//interfata de citire&lt;br /&gt;
			input logic [5:0] addr_read, // 64 locatii =&amp;gt; 6 biti de adresa &lt;br /&gt;
			output logic [7:0] data_read, // fiecare locatie are 8b  &lt;br /&gt;
		// interfata de scriere&lt;br /&gt;
			input logic we,&lt;br /&gt;
			input logic [5:0] addr_write,&lt;br /&gt;
			input logic [7:0] data_write&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic [7:0] memorie_efectiva [0:63]; // memorie cu locatiile de la 0 la 63, fiecare avand 8 biti    &lt;br /&gt;
&lt;br /&gt;
assign data_read = memorie_efectiva[addr_read]; // fara registru pe iesire =&amp;gt; citire asincrona fata de clock &lt;br /&gt;
    &lt;br /&gt;
always_ff @(posedge clock)&lt;br /&gt;
begin    &lt;br /&gt;
    if(we == 1)&lt;br /&gt;
    	begin&lt;br /&gt;
    	memorie_efectiva[addr_write] &amp;lt;= data_write; // scriu la locatia data de &amp;quot;addr_write&amp;quot; din memoria efectiva datele &amp;quot;data_write&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;
Acesta va fi folosit si pe post de modul de &amp;quot;top&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Echivalent se poate folosi si sintaxa cu always ca mai jos.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea memoriei RAM: (fisierul ram64x8_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module ram64x8_v2 // varianta cu always combinational pe citire&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		//interfata de citire&lt;br /&gt;
			input logic [5:0] addr_read,&lt;br /&gt;
			output logic [7:0] data_read,&lt;br /&gt;
		// interfata de scriere&lt;br /&gt;
			input logic we,&lt;br /&gt;
			input logic [5:0] addr_write,&lt;br /&gt;
			input logic [7:0] data_write&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic [7:0] memorie_efectiva [0:63];  &lt;br /&gt;
&lt;br /&gt;
always_comb //  citire asincrona fata de clock &lt;br /&gt;
begin&lt;br /&gt;
	data_read = memorie_efectiva[addr_read]; &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock)&lt;br /&gt;
begin    &lt;br /&gt;
    if(we == 1)&lt;br /&gt;
    	begin&lt;br /&gt;
    	memorie_efectiva[addr_write] &amp;lt;= data_write; // scriu la locatia data de &amp;quot;addr_write&amp;quot; din memoria efectiva datele &amp;quot;data_write&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;
&amp;#039;&amp;#039;&amp;#039;Descrierea test bench-ului memoriei RAM: (fisierul ram64x8_v1_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module ram64x8_tb();&lt;br /&gt;
&lt;br /&gt;
logic clock_tb;&lt;br /&gt;
logic [5:0] addr_read_tb;&lt;br /&gt;
logic [7:0] data_read_tb;&lt;br /&gt;
logic we_tb;&lt;br /&gt;
logic [5:0] addr_write_tb;&lt;br /&gt;
logic [7:0] data_write_tb;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ram64x8_v1 dut&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock_tb),&lt;br /&gt;
		//interfata de citire&lt;br /&gt;
			.addr_read(addr_read_tb), // 64 locatii =&amp;gt; 6 biti de adresa &lt;br /&gt;
			.data_read(data_read_tb), // fiecare locatie are 8b  &lt;br /&gt;
		// interfata de scriere&lt;br /&gt;
			.we(we_tb),&lt;br /&gt;
			.addr_write(addr_write_tb),&lt;br /&gt;
			.data_write(data_write_tb)&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	clock_tb = 0;&lt;br /&gt;
	forever &lt;br /&gt;
		begin&lt;br /&gt;
		#5 clock_tb = ~clock_tb; // perioada totala 10 !!!&lt;br /&gt;
		end&lt;br /&gt;
end    &lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	data_write_tb &amp;lt;= 0;&lt;br /&gt;
	addr_read_tb &amp;lt;= 0; // citind de la o adresa nescrisa inca, iesirea e necunoscuta&lt;br /&gt;
	addr_write_tb &amp;lt;= 0;&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		// incep sa fac scrieri&lt;br /&gt;
	we_tb &amp;lt;= 1;	// scriu data 5 la adresa 10&lt;br /&gt;
	addr_write_tb &amp;lt;= 10;&lt;br /&gt;
	data_write_tb &amp;lt;= 5;&lt;br /&gt;
	addr_read_tb &amp;lt;= 11; // citind de la o adresa nescrisa inca, iesirea e necunoscuta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb &amp;lt;= 0;			// scrierea asta nu se face deoarece nu am write enable activ	&lt;br /&gt;
	addr_write_tb &amp;lt;= 11;&lt;br /&gt;
	data_write_tb &amp;lt;= 10;	&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_write_tb &amp;lt;= 11;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_write_tb &amp;lt;= 12;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb &amp;lt;= 1;&lt;br /&gt;
	addr_write_tb &amp;lt;= 20; // scriere ok &lt;br /&gt;
	data_write_tb &amp;lt;= 42;	// scriu data 42 la adresa 20&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_write_tb &amp;lt;= 51;	// si asta; suprascriu datele anterioare la adresa 20.&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	addr_write_tb &amp;lt;= 21;&lt;br /&gt;
	data_write_tb &amp;lt;= 11;	// scriere ok&lt;br /&gt;
	addr_read_tb &amp;lt;= 20; // citesc de la adresa 20, scrisa anteior deci voi vedea date cunoscute pe iesire.&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	addr_write_tb &amp;lt;= 23;&lt;br /&gt;
	data_write_tb &amp;lt;= 14;	// scriere ok &lt;br /&gt;
	addr_read_tb &amp;lt;= 21; // variez adresa de citire si pot parcurge memorie locatie cu locatie&lt;br /&gt;
	@(posedge clock_tb);	&lt;br /&gt;
	we_tb &amp;lt;= 0;	// opresc scrierea&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&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;
[[Fișier:Ram64X8_waveform.png|1000px]]&lt;br /&gt;
&lt;br /&gt;
In forma de unda de mai sus sunt marcate momentele de timp cand au loc scrieri in memorie (cand am write enable activ si valori cunoscute pentru data si adresa de scriere). Se salveaza valorile imediat la stanga frontului de ceas.&lt;br /&gt;
&lt;br /&gt;
In simularea completa, se poate observa si scrierea in registrii din memorie a datelor dorite  la adresa setata.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
===Exercitiul 1: RAM cu registru la iesire=== &lt;br /&gt;
&lt;br /&gt;
Pornind de la exemplul anterior, se doreste adaugarea unui registru la citirea datelor, astfel citirea devenind sincrona cu semnalul de ceas. In cod acest lucru se poate face foarte usor, punand operatia de citire pe ceas.&lt;br /&gt;
&lt;br /&gt;
Se doreste simularea si apoi testarea fizica a acestei memorii. Simularea noii memorii se face prin executarea a 3 scrieri la adrese diferite si citirea apoi a datelor respective. Sinteza si testarea fizica necesita micsorarea memoriei din cauza numarului limitat de switchuri/butoane al placii. Vom lucra acum cu o memorie de 8 locatii X 4 biti. &lt;br /&gt;
Adresa va fi comandata de switch-uri si datele de intrare din butoane. Se va folosi Button[0] pentru semnalul de &amp;quot;we&amp;quot; (write enable). Afisarea datelor se va face pe leduri.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: RAM multiport citire===&lt;br /&gt;
&lt;br /&gt;
Pornind de la exercitiul 1, se doreste modificarea memoriei astfel incat sa poata fi citite 2 locatii simultan si independent de adresa la care se face scrierea. Se pastreaza citirea sincrona.&lt;br /&gt;
&lt;br /&gt;
Se obtine astfel un circuit a carui interfata este la randul ei compusa din 3 interfete (+semnal comun &amp;quot;clock&amp;quot;): &lt;br /&gt;
&lt;br /&gt;
:- interfata de scriere &lt;br /&gt;
&lt;br /&gt;
:- interfata de citire 0&lt;br /&gt;
&lt;br /&gt;
:- interfata de citire 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Interfata circuitului arata ca in figura de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Ram_64X8_2read_1write_exterior_view.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda corespunzatoare pentru a testa aceasta memorie.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Blocul de registri (register file) din interiorul procesoarelor (vedeti AMP) poate fi o astfel de memorie RAM. Are 2 adrese pentru citirea celor 2 operanzi care intra in ALU si o adresa pentru rezultatul calculului ce este salvat.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Registrul paralel-serie===&lt;br /&gt;
&lt;br /&gt;
Descrieti comportamental un registru paralel-serie. Acesta are rolul de a salva datele de la intrare pe &amp;quot;n&amp;quot; biti (aici 8) si apoi de a le scoate la iesire bit cu bit.&lt;br /&gt;
&lt;br /&gt;
Interfata acestuia este data in desenul de mai jos. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Registru_paralel_serie.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Semnalul de &amp;quot;en&amp;quot; (enable) are rolul de a controla deplasarea, care se executa prin operatia de shiftare la dreapta &amp;quot;&amp;gt;&amp;gt;&amp;quot;. Daca acesta are valoarea &amp;quot;1&amp;quot;, datele salvate se muta la dreapta cu o pozitie.&lt;br /&gt;
:Semnalul de write_en/start/save are rolul de a salva cei 8 biti care urmeaza a fi serializati.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda corespunzatoare pentru a testa aceast circuit (minim 3 scrieri/serializari).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Bonus&amp;#039;&amp;#039;&amp;#039;: Realizati acelasi circuit folosind o descriere structurala.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Registrul serie-paralel===&lt;br /&gt;
&lt;br /&gt;
Descrieti comportamental un registru serie-paralel. Acesta are rolul de a salva date introduse bit cu bit ca apoi sa fie scoase cate &amp;quot;n&amp;quot; biti deodata.&lt;br /&gt;
&lt;br /&gt;
Interfata acestuia este data in desenul de mai jos. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Registru_serie_paralel.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
Semnalul de &amp;quot;en&amp;quot; (enable) are rolul de a controla deplasarea, care se executa prin operatia de shiftare la dreapta &amp;quot;&amp;gt;&amp;gt;&amp;quot;. Daca acesta are valoarea &amp;quot;1&amp;quot;, datele salvate se muta la dreapta cu o pozitie.&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda corespunzatoare pentru a testa aceast circuit (minim 3 scrieri/paralelizari).&lt;br /&gt;
&lt;br /&gt;
Citirea se poate face oricand, desi doar dupa &amp;quot;n&amp;quot; pasi, va fi cu valoarea corecta.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Registrul de intarziere pe 8b===&lt;br /&gt;
&lt;br /&gt;
Prin conectarea in serie a mai multor registri pe 8b (astfel incat data ce iese din unul sa fie intrare pentru urmatorul) se pot construi registri de intarziere cu &amp;quot;x&amp;quot; cicli de ceas. Cum fiecare registru salveaza datele pe ceas, se poate spune ca datele de la iesire sunt intarziate cu un ceas fata de datele de la intrare, astfel o intarziere cu &amp;quot;x&amp;quot; cicli de ceas se obtine prin punerea in serie a &amp;quot;x&amp;quot; registri. &lt;br /&gt;
&lt;br /&gt;
Pornind de la un registru simplu pe 8b (exemplul 1), construiti structural un registru de intarziere cu 4 cicli de ceas. &lt;br /&gt;
&lt;br /&gt;
Testati functionarea acestuia prin simulare. Datale introduse trebuie sa iasa defazate cu 4 cicli de ceas (adica cu 4 cicli de ceas mai tarziu).&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_9_:_Numaratorul&amp;diff=7892</id>
		<title>CID aplicatii 9 : Numaratorul</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_9_:_Numaratorul&amp;diff=7892"/>
		<updated>2024-10-22T13:57:05Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Numărătorul ==&lt;br /&gt;
Numărătorul este cel mai simplu automat, fiind format dintr-un registru (element de memorare) ce reține valoarea curentă a acestuia și un circuit de incrementare (circuit de reacție) ce generează la ieșirea sa valoarea ce va trebui stocată în registru la următorul front crescător de ceas (valoarea curentă incrementată cu 1). &lt;br /&gt;
&lt;br /&gt;
În figura de mai jos este reprezentat un numărător cu reset sincron:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Numarator cu reset.png|600px]]&lt;br /&gt;
&lt;br /&gt;
În cazul de mai sus, cât timp semnalul &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; este activ, valoarea numărătorului va fi 0. Atunci când semnalul &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; nu este activ, numărătorul își va incrementa valoarea la fiecare front crescător de ceas.&lt;br /&gt;
&lt;br /&gt;
== Divizor de frecvență cu factor de divizare putere a lui 2==&lt;br /&gt;
În unele cazuri, apare necesitatea obținerii unor semnale de ceas cu frecvență mai mică decât cea a ceasului de sistem. Aceste noi semnale de ceas pot fi obținute chiar din semnalul de ceas al sistemului, prin circuite care realizează divizarea acestuia. Cea mai simplă divizare a unui semnal de ceas este cea cu factor de divizare egal cu o putere a lui 2. Pentru acest caz, putem folosi un numărător.&lt;br /&gt;
&lt;br /&gt;
Dacă urmărim figura de mai jos în care sunt reprezentate variațiile fiecărui bit în timpul funcționării unui numărător pe 4 biți, observăm că, cu cât ordinul bitului crește (este mai semnificativ), frecvența de variație este mai mică. Între frecvențele de variație corespunzătoare a doi biți succesivi există următoarea relație: frecvența unui bit este de două ori mai mică decât frecvența bitului anterior (mai puțin semnificativ).&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Divizare frecventa.png]]&lt;br /&gt;
&lt;br /&gt;
Observând că frecvența bitului 0 este de două ori mai mică decât cea a ceasului, putem concluziona că frecvența de variație a bitului cu indicele N este dată de: &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;f&amp;lt;sub&amp;gt;bN&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039; = &amp;#039;&amp;#039;f&amp;lt;sub&amp;gt;clk&amp;lt;/sub&amp;gt; / 2&amp;lt;sup&amp;gt;N+1&amp;lt;/sup&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Așadar, pentru a realiza un divizor de frecvență cu factor de divizare putere a lui 2, putem folosi un numărător îndeajuns de mare, din care extragem bitul cu frecvența de variație egală cu frecvența dorită.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Exemple==&lt;br /&gt;
===Exemplul 1: Implementarea unui numărător cu reset sincron===&lt;br /&gt;
În acest exemplu vom realiza implementarea numărătorului cu reset sincron prezentat în figura din secțiunea de introducere teoretică. În plus, vom folosi parametrul WIDTH pentru a controla dimensiunea acestuia.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea Numărătorului cu reset sincron&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module Numarator&lt;br /&gt;
#(parameter WIDTH = 8)&lt;br /&gt;
(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic reset_n,&lt;br /&gt;
    output logic [WIDTH-1:0] count  &lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset_n == 0)&lt;br /&gt;
        count &amp;lt;= 0;&lt;br /&gt;
    else&lt;br /&gt;
        count &amp;lt;= count + 1;  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru numărător&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps&lt;br /&gt;
&lt;br /&gt;
module Numarator_TB();&lt;br /&gt;
&lt;br /&gt;
parameter WIDTH_T = 5;&lt;br /&gt;
logic reset_n_t, clock_t;&lt;br /&gt;
logic [WIDTH_T-1:0] count_t;&lt;br /&gt;
	&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
	&lt;br /&gt;
initial begin&lt;br /&gt;
        reset_n_t = 0;&lt;br /&gt;
    #2 	reset_n_t = 1;&lt;br /&gt;
    #500 $stop();	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
Numarator #(.WIDTH(WIDTH_T)) DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset_n(reset_n_t),&lt;br /&gt;
    .count(count_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Cât timp semnalul &amp;#039;&amp;#039;reset&amp;#039;&amp;#039; este inactiv, numărătorul își va incrementa valoarea la fiecare front crescător de ceas. Când va ajunge la valoarea sa maximă (de exemplu, 31 pentru un numărător pe 5 biți), va avea loc o depășire și având la dispozitie un număr limitat de biți (de exemplu, 5), semnalul de ieșire va deveni 0 (reținem doar cei mai puțin semnificativi 5 biți), circuitul reluând numărarea de la capat.&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Observarea vitezei de variație a biților unui numărător===&lt;br /&gt;
În acest exemplu vom realiza implementarea unui divizor de frecvență ce generează la ieșire 4 semnale de ceas cu următoarele frecvențe:&lt;br /&gt;
* &amp;#039;&amp;#039;clkout1&amp;#039;&amp;#039;: semnal de ceas cu frecvența de 1 Hz.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout2&amp;#039;&amp;#039;: semnal de ceas cu frecvența de 2 Hz.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout4&amp;#039;&amp;#039;: semnal de ceas cu frecvența de 4 Hz.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout8&amp;#039;&amp;#039;: semnal de ceas cu frecvența de 8 Hz.&lt;br /&gt;
&lt;br /&gt;
Dacă aplicăm formula &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;f&amp;lt;sub&amp;gt;bN&amp;lt;/sub&amp;gt;&amp;#039;&amp;#039; = &amp;#039;&amp;#039;f&amp;lt;sub&amp;gt;clk&amp;lt;/sub&amp;gt; / 2&amp;lt;sup&amp;gt;N+1&amp;lt;/sup&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; cunoscând că frecvența de ceas a FPGA-ului este de 100 MHz, vom obține:&lt;br /&gt;
* &amp;#039;&amp;#039;clkout1&amp;#039;&amp;#039; poate fi obținut prin bitul 26 al unui numărător.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout2&amp;#039;&amp;#039; poate fi obținut prin bitul 25 al unui numărător.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout4&amp;#039;&amp;#039; poate fi obținut prin bitul 24 al unui numărător.&lt;br /&gt;
* &amp;#039;&amp;#039;clkout8&amp;#039;&amp;#039; poate fi obținut prin bitul 23 al unui numărător.&lt;br /&gt;
&lt;br /&gt;
Din rezultatele de mai sus, rezultă că avem nevoie de un numărător pe 27 biți, astfel încât să putem folosi bitul cel mai semnificativ (bitul 26) pentru generarea semnalului de ceas cu frecvența cea mai mică.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea SystemVerilog a circuitului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module clock_generator(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic clkout1,&lt;br /&gt;
    output logic clkout2,&lt;br /&gt;
    output logic clkout4,&lt;br /&gt;
    output logic clkout8,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
logic [26:0] count;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        count &amp;lt;= 0;&lt;br /&gt;
    else&lt;br /&gt;
        count &amp;lt;= count + 1;  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
assign clkout1 = count[26];&lt;br /&gt;
assign clkout2 = count[25];&lt;br /&gt;
assign clkout4 = count[24];&lt;br /&gt;
assign clkout8 = count[23];&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Cerința ca reset să fie activ în 1 este impusă de logica în care lucrează butoanele FPGA-ului.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea circuitului pe FPGA&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Realizați sinteza circuitului pe FPGA, ținând cont de următoarele constrângeri de I/O:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
||&amp;#039;&amp;#039;&amp;#039;Port&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;Conexiune&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| clock || CLK_100MHz&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| reset || Button 0 &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| clkout1 || LED3&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| clkout2  || LED2&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| clkout4  || LED1 &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| clkout8  || LED0 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Observați viteza cu care fiecare din LED-uri se stinge și se aprinde.&lt;br /&gt;
&lt;br /&gt;
== Exerciții==&lt;br /&gt;
===Exercițiul 1===&lt;br /&gt;
Implementați un numărător parametrizat cu reset sincron și semnal de &amp;#039;&amp;#039;enable&amp;#039;&amp;#039;. Semnalul &amp;#039;&amp;#039;enable&amp;#039;&amp;#039; controlează funcționarea numărătorului astfel: când este activ (egal cu 1), permite funcționarea normală (incrementare la fiecare front crescător de ceas); când este inactiv (egal cu 0), va determina numărătorul să își păstreze valoarea curentă.&lt;br /&gt;
&lt;br /&gt;
Implementați și un modul de test care să testeze funcționarea corectă a circuitului.&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 2===&lt;br /&gt;
Implementați un numărător parametrizat cu reset sincron și capacitatea de a număra crescător sau descrescător. Controlul direcției de numărare se va realiza cu ajutorul unui semnal &amp;#039;&amp;#039;count_updown&amp;#039;&amp;#039;, care controlează funcționarea numărătorului astfel: când este 0, numărătorul va număra crescător, prin incrementarea valorii curente, iar când este 1, numărătorul va număra descrescător, prin decrementarea valorii curente&lt;br /&gt;
&lt;br /&gt;
Implementați și un modul de test care să testeze funcționarea corectă a circuitului.&lt;br /&gt;
&lt;br /&gt;
===Exercițiul 3===&lt;br /&gt;
Implementați circuitul descris prin schema de mai jos, știind că:&lt;br /&gt;
* COUNTER este un numărător pe 32 biți fără reset.&lt;br /&gt;
* RAM este o memorie 16x4b, cu citire sincrona.&lt;br /&gt;
* ROM este o memorie 16x4b, ce are descrierea prezentată mai jos.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Cid_lab6.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea modulului ROM&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module ROM(&lt;br /&gt;
    input logic [3:0] in,&lt;br /&gt;
    output logic [3:0] out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
always_comb&lt;br /&gt;
    case(in)&lt;br /&gt;
        0: out = 4&amp;#039;b0000;&lt;br /&gt;
        1: out = 4&amp;#039;b0110;&lt;br /&gt;
        2: out = 4&amp;#039;b0011;&lt;br /&gt;
        3: out = 4&amp;#039;b1110;&lt;br /&gt;
        4: out = 4&amp;#039;b1011;&lt;br /&gt;
        5: out = 4&amp;#039;b1111;&lt;br /&gt;
        6: out = 4&amp;#039;b0111;&lt;br /&gt;
        7: out = 4&amp;#039;b1100;&lt;br /&gt;
        8: out = 4&amp;#039;b0001;&lt;br /&gt;
        9: out = 4&amp;#039;b0101;&lt;br /&gt;
        10: out = 4&amp;#039;b1101;&lt;br /&gt;
        11: out = 4&amp;#039;b1010;&lt;br /&gt;
        12: out = 4&amp;#039;b0010;&lt;br /&gt;
        13: out = 4&amp;#039;b0100;&lt;br /&gt;
        14: out = 4&amp;#039;b1000;&lt;br /&gt;
        15: out = 4&amp;#039;b1001;&lt;br /&gt;
        default: out = 4&amp;#039;b0000;&lt;br /&gt;
    endcase&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Realizați un modul de test în care să scrieți memoria RAM cu date, astfel încât să se realizeze citirea memoriei ROM în ordine, la fiecare ciclu de ceas (adresa 0 -&amp;gt; adresa 1 -&amp;gt; ... -&amp;gt; adresa 15 -&amp;gt; adresa 0 -&amp;gt; ...)&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_10_:_Aplicatii_cu_numaratoare&amp;diff=7891</id>
		<title>CID aplicatii 10 : Aplicatii cu numaratoare</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_10_:_Aplicatii_cu_numaratoare&amp;diff=7891"/>
		<updated>2024-10-22T13:56:45Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Teorie==&lt;br /&gt;
&lt;br /&gt;
Numaratoarele au extrem de multe aplicatii in lumea reala, cateva dintre acestea fiind descrise mai jos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exemplu: Numaratul apasarilor unui buton==&lt;br /&gt;
	&lt;br /&gt;
Un prim sistem simplu cu numarator poate fi cel care contorizeaza de cate ori a fost apasat un buton sau, echivalent, cate persoane/masini au trecut printr-un senzor, de cate ori a fost deschisa o usa etc. Acest sistem se poate apoi dezvolta cu usurinta pentru a numara si oamenii care trec invers prin respectivul set de senzori prin adaugarea functionalitatii de up/down la numarator.&lt;br /&gt;
&lt;br /&gt;
Un astfel de sistem simplu (varianta doar cu numarat intrari) ar arata in felul urmator: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Aplicatii_numarator_exemplu_contor_senzor.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
Circuitul de debounce are rolul de a &amp;quot;curata&amp;quot; semnalul de intrare, astfel incat chiar si in prezenta zgomotului sau a unei activari indelungate a senzorului/butonului, sa se contorizeze un singur eveniment. O explicatie mai detaliata puteti gasi [[Circuitul_de_debounce|aici]].&lt;br /&gt;
&lt;br /&gt;
Numaratorul numara evenimentele.&lt;br /&gt;
&lt;br /&gt;
Transcodorul pentru display cu 7 segmente este apoi folosit pentru o mai usoara vizualizare a numarului curent. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; transcodorul pentru 7seg din exemplul de mai jos este in logica negativa. Daca circuitul fizic este in logica pozitiva trebuie adaugat un inversor la iesirea din acesta. De asemnea consider segmentul &amp;quot;a&amp;quot; pe bitul &amp;quot;0&amp;quot; si segmentul &amp;quot;h&amp;quot; pe bitul &amp;quot;6&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea debouncer-ului (fisierul debounce.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module debounce&lt;br /&gt;
	#(&lt;br /&gt;
		parameter limit = 20&amp;#039;d650000&lt;br /&gt;
	) (&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic in,&lt;br /&gt;
		output logic out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
logic [19:0] counter; // observatie: si circuitul de debounce foloseste un numarator&lt;br /&gt;
logic hit;&lt;br /&gt;
&lt;br /&gt;
assign out = (counter == limit);&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) &lt;br /&gt;
begin&lt;br /&gt;
	if(in == 0) &lt;br /&gt;
		begin&lt;br /&gt;
		counter &amp;lt;= 0;&lt;br /&gt;
		hit &amp;lt;= 0;        &lt;br /&gt;
		end &lt;br /&gt;
	else &lt;br /&gt;
		begin&lt;br /&gt;
		if(counter == limit) &lt;br /&gt;
			begin&lt;br /&gt;
			hit &amp;lt;= 1;&lt;br /&gt;
			counter &amp;lt;= counter + 1;&lt;br /&gt;
			end &lt;br /&gt;
		else &lt;br /&gt;
			begin&lt;br /&gt;
			if(in == 1 &amp;amp; hit == 0) &lt;br /&gt;
				begin&lt;br /&gt;
				counter &amp;lt;= counter + 1;&lt;br /&gt;
				end&lt;br /&gt;
			end&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;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea numaratorului pe 4b(fisierul counter_4b.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module counter_4b&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset,&lt;br /&gt;
		input logic en,&lt;br /&gt;
		output logic [3:0] out&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
always_ff @(posedge clock)&lt;br /&gt;
begin&lt;br /&gt;
	if(reset == 1)&lt;br /&gt;
		begin&lt;br /&gt;
		out &amp;lt;=0;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		begin&lt;br /&gt;
		if(en == 1)&lt;br /&gt;
			begin&lt;br /&gt;
			out &amp;lt;= out + 1;&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			begin&lt;br /&gt;
			out &amp;lt;= out;&lt;br /&gt;
			end&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;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea transcodorului pentru afisaj cu 7seg(fisierul transcodor_7seg.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module transcodor_7seg				// logica negativa &lt;br /&gt;
	(&lt;br /&gt;
		input logic [3:0] in,&lt;br /&gt;
  		output logic [6:0] out&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
always_comb&lt;br /&gt;
begin&lt;br /&gt;
	case(in)&lt;br /&gt;
		4&amp;#039;d0: out = 7&amp;#039;b1000000;// h....a&lt;br /&gt;
		4&amp;#039;d1: out = 7&amp;#039;b1111001;&lt;br /&gt;
		4&amp;#039;d2: out = 7&amp;#039;b0100100;&lt;br /&gt;
		4&amp;#039;d3: out = 7&amp;#039;b0110000;&lt;br /&gt;
		4&amp;#039;d4: out = 7&amp;#039;b0011001;&lt;br /&gt;
		4&amp;#039;d5: out = 7&amp;#039;b0010010;&lt;br /&gt;
		4&amp;#039;d6: out = 7&amp;#039;b0000010;&lt;br /&gt;
		4&amp;#039;d7: out = 7&amp;#039;b1111000;&lt;br /&gt;
		4&amp;#039;d8: out = 7&amp;#039;b0000000;&lt;br /&gt;
		4&amp;#039;d9: out = 7&amp;#039;b0010000;&lt;br /&gt;
		4&amp;#039;d10: out = 7&amp;#039;b0001000;&lt;br /&gt;
		4&amp;#039;d11: out = 7&amp;#039;b0000011;&lt;br /&gt;
		4&amp;#039;d12: out = 7&amp;#039;b1000110;&lt;br /&gt;
		4&amp;#039;d13: out = 7&amp;#039;b0100001;&lt;br /&gt;
		4&amp;#039;d14: out = 7&amp;#039;b0000110;&lt;br /&gt;
		4&amp;#039;d15: out = 7&amp;#039;b0001110;&lt;br /&gt;
		default: out = 7&amp;#039;b1111111;//tot stins &lt;br /&gt;
	endcase &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;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea sistemului, modulul de top (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset,&lt;br /&gt;
		input logic button,&lt;br /&gt;
		output logic [6:0] out    // logica negativa &lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic debounce_0_X_out;&lt;br /&gt;
logic [3:0] counter_4b_0_X_out;   &lt;br /&gt;
    &lt;br /&gt;
debounce&lt;br /&gt;
	#(&lt;br /&gt;
		.limit(20&amp;#039;d50_000)&lt;br /&gt;
	) debounce_0 (&lt;br /&gt;
		.clock(clock),&lt;br /&gt;
		.in(button),&lt;br /&gt;
		.out(debounce_0_X_out)&lt;br /&gt;
	);&lt;br /&gt;
	    &lt;br /&gt;
counter_4b counter_4b_0&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock),&lt;br /&gt;
		.reset(reset),&lt;br /&gt;
		.en(debounce_0_X_out),&lt;br /&gt;
		.out(counter_4b_0_X_out)&lt;br /&gt;
    );    &lt;br /&gt;
    &lt;br /&gt;
transcodor_7seg	transcodor_7seg_0			// logica negativa &lt;br /&gt;
	(&lt;br /&gt;
		.in(counter_4b_0_X_out),&lt;br /&gt;
  		.out(out)&lt;br /&gt;
    );    &lt;br /&gt;
 &lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea test bench-ului(fisierul tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module tb();&lt;br /&gt;
&lt;br /&gt;
logic clock_tb;&lt;br /&gt;
logic reset_tb;&lt;br /&gt;
logic button_tb;&lt;br /&gt;
logic [6:0] out_tb;&lt;br /&gt;
&lt;br /&gt;
top dut&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock_tb),&lt;br /&gt;
		.reset(reset_tb),&lt;br /&gt;
		.button(button_tb),&lt;br /&gt;
		.out(out_tb)    // logica negativa &lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	clock_tb = 0;&lt;br /&gt;
	forever&lt;br /&gt;
		begin&lt;br /&gt;
		#5 clock_tb = ~clock_tb;&lt;br /&gt;
		end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	reset_tb = 0;&lt;br /&gt;
	button_tb = 0;&lt;br /&gt;
	&lt;br /&gt;
	#50;&lt;br /&gt;
	reset_tb = 1;&lt;br /&gt;
	#50;&lt;br /&gt;
	reset_tb = 0;&lt;br /&gt;
	#100;&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) 	// vreau 5 apasari de buton&lt;br /&gt;
		begin&lt;br /&gt;
		button_tb = 1;&lt;br /&gt;
		repeat(70_000)				&lt;br /&gt;
			begin&lt;br /&gt;
			@(posedge clock_tb);&lt;br /&gt;
			end&lt;br /&gt;
		button_tb = 0;&lt;br /&gt;
		repeat(70_000)&lt;br /&gt;
			begin&lt;br /&gt;
			@(posedge clock_tb);&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
	#1000 $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;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
=== Exercitiul 1: Divizor de frecventa cu puteri ale lui 2=== &lt;br /&gt;
&lt;br /&gt;
Divizorul de frecventa are rolul de a genera un semnal de ceas mai lent din semnalul de ceas principal. &lt;br /&gt;
El este alcatuit doar dintr-un numarator, iar fiecare bit al acestuia va fi practic un semnal de ceas cu frecventa din ce in ce mai mica astfel (la jumate): &lt;br /&gt;
&lt;br /&gt;
bit[0] - frecventa de 2 ori mai mica decat semnalul de ceas&lt;br /&gt;
 &lt;br /&gt;
bit[1] - frecventa de 2 ori mai mica decat bit[0], deci de 4 ori mai mica decat semnalul de ceas &lt;br /&gt;
&lt;br /&gt;
bit[2] - frecventa de 2 ori mai mica decat bit[1], deci de 8 ori mai mica decat semnalul de ceas &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Acest lucru se poate observa si in poza ce urmeaza: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Freq_divider_output.png| 800px]] &lt;br /&gt;
&lt;br /&gt;
Implementati acest circuit, si folosind ledurile prezente pe placa, incercati sa conectati bitul corespunzator la leduri astfel incat cel mai din dreapta led sa clipeasca cu o frecventa cat mai apropiata de 1s. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Printr-un astfel de divizor de frecventa minimal, un numar foarte mic de frecvente poate fi generat. Daca se doreste generarea unui semnal periodic cu o perioada exacta, diferita de cele posibile prin acest mecanism, se poate construi urmatorul circuit:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: Divizor de frecventa ce poate genera orice perioada=== &lt;br /&gt;
&lt;br /&gt;
Un astfel de divizor de frecventa este construit ca in figura de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Freq_div_orice_freq.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
Prin adaugarea constantei &amp;quot;limit&amp;quot;, perioada semnalului de iesire poate sa fie orice multiplu a perioadei semnalului de ceas. &lt;br /&gt;
&lt;br /&gt;
Bistabilul de tip t, se modifica atunci cand limita este atinsa si practic iesirea lui este semnalul periodic dorit (cu observatia ca o perioada a semnalului de iesire necesita 2 numarari pana la limita).&lt;br /&gt;
&lt;br /&gt;
Sa se calculeze valoarea necesara pentru &amp;quot;limit&amp;quot; astfel incat pe leduri sa se genereze semnal cu perioada exact 1s.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; In FPGA exista fizic trasee speciale pentru reset si ca sinteza sa le foloseasca pe acestea in mod optim nu este recomandat sa se puna logica (cum e aici poarta sau) pe acestea. Modificati schema de mai sus astfel incat sa eliminati respectiva poarta de pe reset. (Sfat: numaratorul va avea acum si intrari de load: semnalul de comanda si data propriu zisa)&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: PWM (Pulse Width Modulation)===&lt;br /&gt;
&lt;br /&gt;
PWM este un concept folosit foarte des in multiple ramuri ale ingineriei, de la transmisiunea informatiei pana la controlul motoarelor sau al intensitatii ledurilor din instalatii de Craciun. El se refera la a avea un semnal periodic cu factor de umplere variabil, asa cum este aratat in poza de mai jos :&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm.png| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generarea unui astfel de semnal periodic se face printr-un numarator si un comparator, ca in figura de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm_schematic.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raportul dintre limita pusa si valoarea la care numaratorul se reseteaza este practic factorul de umplere selectat.&lt;br /&gt;
&lt;br /&gt;
Pentru testare pe placa, cei 6b ai limitei provin de la switch-uri si butoane. Afisarea se face pe led[0].&lt;br /&gt;
&lt;br /&gt;
Testati acest circuit in simulare si apoi implementati pe placa pentru o valoare fixa a limitei. Implementati in paralel mai multe generatoare de semnal PWM cu limite diferite, astfel incat sa observati diferentele de intentistate dintre ledurile comandate de acestea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: PWM cu limita variabila===&lt;br /&gt;
&lt;br /&gt;
Un exemplu foarte uzual de folosire a PWM este aprinderea ledurilor cu diverse pattern-uri. Factorul de umplere determina intensitatea cu care ledul este aprins. Un PWM cu o limita variabila automata va face ledul sa para din ce in ce mai stins sau din ce in ce mai luminos (exemplu: instalatii de Craciun). Combinand asta cu leduri RGB se obtin efecte de schimbare a culorii ledului aparent la intamplare. &lt;br /&gt;
&lt;br /&gt;
Un astfel de circuit se realizeaza punand inca un numarator in locul limitei, ca in poza de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm_duty_cycle_up_schematic.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru o functionalitate suplimentara, anume a pastra un anumit factor de umplere mai multe perioade, am adaugat inca un numarator.&lt;br /&gt;
&lt;br /&gt;
Pentru claritatea desenului, nu am mai tras efectiv firul de ceas catre intrarile unde acesta se duce.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rezultatul este: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm_duty_cycle_up_output.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Testati circuitul propus prin simulare si apoi vizualizati implementarea sa pe placa. Alegeti limite potrivite astfel incat sa puteti observa usor rezultatul.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Bonus:&amp;#039;&amp;#039;&amp;#039; Incercati sa adaugati si parametri pentru LIMIT_DUTY_CYCLE_LOW si LIMIT_DUTY_CYCLE_HIGH, care sa permita factorului de umplere sa varieze doar intre ele (numaratorul va avea nevoie de intrari pentru comanda de load si data load, ca sa poata incepe de la orice valoare).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Bonus:&amp;#039;&amp;#039;&amp;#039; Modificati circuitul astfel incat semnalul de iesire sa isi schimbe sensul de variatie al factorului de umplere cand ajunge cu acesta la capat. In forma curenta factorul de umplere creste de la 0% la 100% si apoi se reseteaza brusc la 0%, repetand acest ciclu. Se vrea ca la ajungerea la 100% sa inceapa o scadere treptata catre 0%, urmata apoi de o urcare s.a.m.d.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Ceas===&lt;br /&gt;
&lt;br /&gt;
Un ceas poate fi construit cifra cu cifra, folosind numaratoare si comparatoare (si transcodoare pentru display cu 7seg ca sa se vada totul mai bine pe placa).&lt;br /&gt;
&lt;br /&gt;
Incercati sa implementati un ceas cu milisecunde, secunde si minute in varianta comportamentala. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Va fi nevoie fie separat, fie in modul de un numarator cu frecventa rezolutiei dorite (aici 1 ms).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Codul va contine multe &amp;quot;if&amp;quot; de tipul &amp;quot;daca cifra unitatilor secundelor a ajuns la 10, se face 0 si cresc cifra zecilor&amp;quot;, repetate pentru fiecare cifra.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Incercati si o implementare structurala a ceasului, mergand pe aceeasi idee. Fiecare cifra va contine numaratorul ei. Cand numaratorul unei cifre ajunge ajunge la limita sa, va da enable pentru numaratorul cifrei urmatoare. Daca este nevoie se pot folosi si porti aditionale (ex: ca sa creasca minutul cifra zecilor secundelor trebuie sa fie 5 si cifra unitatilor secundelor trebuie sa fie 9). &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Va fi nevoie de un numarator cu frecventa rezolutiei dorite (aici 1 ms sau 1s).&lt;br /&gt;
 &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Pentru a scrie mai putin puteti face un numarator doar cu secunde si minute. Principiul de baza este acelasi si daca aveati milisecunde.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Simularea a cateva milisecunde sau chiar secunde este un proces indelungat (dureaza minute-ore fizice), astfel strict pentru simulari se recomanda ceasul sa functioneze cu microsecunde sau milisecunde maxim.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_11_:_Automate_finite&amp;diff=7890</id>
		<title>CID aplicatii 11 : Automate finite</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_11_:_Automate_finite&amp;diff=7890"/>
		<updated>2024-10-22T13:56:22Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Automate finite ==&lt;br /&gt;
&lt;br /&gt;
Automatul finit este folosit pentru a descrie sisteme ce tranziteaza un numar finit de stari. Acest tip de sistem este foarte util atunci cand starile nu sunt tranzitate intr-un mod simplu, evident sau repetitiv. &lt;br /&gt;
&lt;br /&gt;
Automatul finit, numit și FSM (Finite State Machine), este un model matematic de computație, definit de următoarele elemente:&lt;br /&gt;
* O mulțime finită de simboluri de intrare, numită alfabet de intrare;&lt;br /&gt;
* O mulțime finită și nevidă de simboluri de ieșire, numită alfabet de ieșire;&lt;br /&gt;
* O mulțime finită și nevidă de stări, din care doar una, numită starea curentă, este activă la un moment dat;&lt;br /&gt;
* O stare inițială, care face parte din mulțimea stărilor;&lt;br /&gt;
* O funcție de tranziție a stărilor, care calculează starea următoare a automatului în funcție de starea curentă și de simbolul de intrare;&lt;br /&gt;
* O funcție de calcul a ieșirii, care determină simbolul de ieșire în funcție de starea curentă (în cazul automatelor de tip Moore) sau în funcție de starea curentă și de simbolul de intrare (în cazul automatelor de tip Mealy).&lt;br /&gt;
&lt;br /&gt;
[[[[Fișier:Fsm.png]]]]&lt;br /&gt;
&lt;br /&gt;
La fiecare front al ceasului, valoarea stării următoare, calculată de către CLC, va fi încărcată în registru. Dacă registrul are n biți, numărul maxim de stări care pot fi reprezentate este 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt;. Acest număr poate fi mai mic, în funcție de schema de codare a stărilor. De exemplu, pentru n = 4, folosind codarea binară se pot reprezenta cel mult 16 stări (0000, 0001, 0010, ..., 1111), în timp ce pentru codarea one-hot, în care doar un singur bit poate lua valoarea 1, se pot reprezenta 4 stări (1000, 0100, 0010, 0001).&lt;br /&gt;
&lt;br /&gt;
Pentru a reprezenta comportamentul unui automat finit, putem folosi grafuri sau organigrame, conventiile de notare depinzand de tipul automatului (Moore sau Mealy).&lt;br /&gt;
&lt;br /&gt;
== Exemple == &lt;br /&gt;
=== Exemplul 1: Automat ce detecteaza secvente de tipul 11....100....0===&lt;br /&gt;
In acest exemplu va fi implementat un automat care detecteaza secventele de tipul 11....100....0. Pentru aceasta, automatul va avea o intrare pe un bit (&amp;#039;&amp;#039;in&amp;#039;&amp;#039;, pe care va veni secventa de biti) si doua iesiri: &amp;#039;&amp;#039;detectOk&amp;#039;&amp;#039;, care semnalizeaza prin 1 ca nu a fost inca detectata o secventa ilegala si &amp;#039;&amp;#039;detectFail&amp;#039;&amp;#039;, care semnalizeaza prin 1 ca a fost detectata o secventa ilegala (un 1 dupa 0). &lt;br /&gt;
&lt;br /&gt;
Automatul va avea 3 stari: &lt;br /&gt;
* Q0 - STATE_READ1: automatul intra in aceasta stare la reset si va ramane in aceasta atata timp cat intrarea este 1 (inca nu a aparut niciun 0).&lt;br /&gt;
* Q1 - STATE_READ0: automatul intra in aceasta stare atunci cand apare pe intrare primul 0 si va ramane in aceasta atata timp cat pe intrare este 0.&lt;br /&gt;
* Q2 - STATE_ERROR: automatul intra in aceasta stare atunci cand apare un 1 dupa 0 si va ramane blocat aici pana la reset.&lt;br /&gt;
&lt;br /&gt;
Pentru a coda cele 3 stari avem nevoie de minim 2 biti: STATE_READ1 = 2&amp;#039;b00, STATE_READ0 = 2&amp;#039;b01, STATE_ERROR = 2&amp;#039;b10.&lt;br /&gt;
&lt;br /&gt;
Graful automatului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Organigrama FSM 111000.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea automatului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM1(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic detectOk,&lt;br /&gt;
    output logic detectFail&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
//Se asociaza sirurilor de biti folositi pentru codarea starilor nume ce pot fi folosite mai usor in cod.&lt;br /&gt;
//La compilare, numele vor fi inlocuite in cod cu numerele asociate la inceput.&lt;br /&gt;
localparam STATE_READ1 = 2&amp;#039;b00;&lt;br /&gt;
localparam STATE_READ0 = 2&amp;#039;b01;&lt;br /&gt;
localparam STATE_ERROR = 2&amp;#039;b10;&lt;br /&gt;
&lt;br /&gt;
logic [1:0] state, state_next;&lt;br /&gt;
&lt;br /&gt;
//registrul de stare&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= STATE_READ1;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
//circuit combinational pentru calculul starii urmatoare&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        STATE_READ1: begin&lt;br /&gt;
                         if(in == 0) state_next = STATE_READ0;&lt;br /&gt;
                     end&lt;br /&gt;
        STATE_READ0: begin&lt;br /&gt;
                         if(in == 1) state_next = STATE_ERROR;&lt;br /&gt;
                     end&lt;br /&gt;
        STATE_ERROR: state_next = STATE_ERROR;&lt;br /&gt;
        default: state_next = STATE_READ1;&lt;br /&gt;
    endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//circuit combinational pentru calculul iesirilor&lt;br /&gt;
assign detectOk   = (state == STATE_READ0) || (state == STATE_READ1);&lt;br /&gt;
assign detectFail = (state == STATE_ERROR);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru FSM1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM1_TB();&lt;br /&gt;
&lt;br /&gt;
logic  clock_t;&lt;br /&gt;
logic  reset_t;&lt;br /&gt;
logic  in_t;&lt;br /&gt;
logic detectOk_t;&lt;br /&gt;
logic detectFail_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
        in_t = 1;&lt;br /&gt;
        reset_t = 1;&lt;br /&gt;
    #2  reset_t = 0;&lt;br /&gt;
    #10 in_t = 0;&lt;br /&gt;
    #10 in_t = 1;&lt;br /&gt;
    #10 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
FSM1 DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset(reset_t),&lt;br /&gt;
    .in(in_t),&lt;br /&gt;
    .detectOk(detectOk_t),&lt;br /&gt;
    .detectFail(detectFail_t)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Automat ce detecteaza fronturile crescatoare ale unui semnal===&lt;br /&gt;
Automatul ce detecteaza fronturile crescatoare are un singur semnal de intrare &amp;#039;&amp;#039;in&amp;#039;&amp;#039;, care reprezinta semnalul analizat si o singura iesire, &amp;#039;&amp;#039;out&amp;#039;&amp;#039;, generand pe aceasta un puls lung cat o perioada de ceas la fiecare aparitie a unui front crescator pe &amp;#039;&amp;#039;in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Vom avea nevoie de 3 stari:&lt;br /&gt;
* Q0: automatul intra in aceasta stare la reset si va ramane in aceasta atata timp cat intrarea este 0 (inca nu a aparut niciun front crescator).&lt;br /&gt;
* Q1: automatul intra in aceasta stare atunci cand apare pe intrare un front crescator. Dupa aparitia frontului crescator sunt doua posibilitati: linia ramane in 1, ceea ce duce la trecerea in starea Q2 care va duce iesirea in 0 dupa o perioada de ceas, sau linia trece in 0 dupa un ciclu de ceas, ceea ce duce la revenirea in starea Q0.&lt;br /&gt;
* Q2: automatul intra in aceasta stare atunci cand linia de intrare ramane in 1 mai mult de o perioada de ceas. Automatul va ramane in aceasta stare atata timp cat &amp;#039;&amp;#039;in&amp;#039;&amp;#039; ramane in 1 si va reveni in starea Q0 imediat ce &amp;#039;&amp;#039;in&amp;#039;&amp;#039; revine in 0.&lt;br /&gt;
&lt;br /&gt;
Graful automatului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Organigrama FSM rising edge.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea automatului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_Moore(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
localparam Q0 = 2&amp;#039;b00;&lt;br /&gt;
localparam Q1 = 2&amp;#039;b01;&lt;br /&gt;
localparam Q2 = 2&amp;#039;b10;&lt;br /&gt;
&lt;br /&gt;
logic [1:0] state, state_next;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= Q0;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        Q0: begin&lt;br /&gt;
                if(in == 1) state_next = Q1;&lt;br /&gt;
            end&lt;br /&gt;
        Q1: begin&lt;br /&gt;
                if(in == 0) state_next = Q0;&lt;br /&gt;
                if(in == 1) state_next = Q2;&lt;br /&gt;
            end&lt;br /&gt;
        Q2: begin&lt;br /&gt;
                if(in == 0) state_next = Q0;&lt;br /&gt;
            end&lt;br /&gt;
        default: state_next = Q0;&lt;br /&gt;
	endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
assign out   = (state == Q1); // iesirea depinde numai de stare =&amp;gt; Moore&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_mealy(&lt;br /&gt;
    input logic clock,&lt;br /&gt;
    input logic in,&lt;br /&gt;
    input logic reset,&lt;br /&gt;
    output logic out&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
localparam stare_wait_1 = 1&amp;#039;b0;&lt;br /&gt;
localparam stare_wait_0 = 1&amp;#039;b1;&lt;br /&gt;
&lt;br /&gt;
logic [1:0] state, state_next;&lt;br /&gt;
&lt;br /&gt;
always_ff @(posedge clock) begin&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
        state &amp;lt;= stare_wait_1;&lt;br /&gt;
    else&lt;br /&gt;
        state &amp;lt;= state_next;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_comb begin&lt;br /&gt;
    state_next = state;&lt;br /&gt;
    case(state)&lt;br /&gt;
        stare_wait_1: begin&lt;br /&gt;
                if(in == 1) state_next = stare_wait_0;&lt;br /&gt;
            end&lt;br /&gt;
        stare_wait_0: begin&lt;br /&gt;
                if(in == 0) state_next = stare_wait_1;&lt;br /&gt;
            end&lt;br /&gt;
        default: state_next = Q0;&lt;br /&gt;
	endcase&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
	// daca pana acum semnalul a fost &amp;quot;0&amp;quot; si astept sa vina &amp;quot;1&amp;quot; si intrarea chiar vine &amp;quot;1&amp;quot; =&amp;gt; am avut front crescator&lt;br /&gt;
assign out = (state==stare_wait_1) &amp;amp; (in==1); // in apare aici =&amp;gt; dependenta iesiri de intrare =&amp;gt; Mealy&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea unui modul de test pentru FSM2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module FSM2_TB();&lt;br /&gt;
&lt;br /&gt;
logic  clock_t;&lt;br /&gt;
logic  reset_t;&lt;br /&gt;
logic  in_t;&lt;br /&gt;
logic out_t;&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
    clock_t = 0;&lt;br /&gt;
    forever #1 clock_t = ~clock_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial begin&lt;br /&gt;
        in_t = 0;&lt;br /&gt;
        reset_t = 1;&lt;br /&gt;
    #2  reset_t = 0;&lt;br /&gt;
    #10 in_t = 1;&lt;br /&gt;
    #5	in_t = 0;&lt;br /&gt;
    #10 in_t = 1;&lt;br /&gt;
    #5	in_t = 0;&lt;br /&gt;
    #10 $stop();&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
FSM2_Moore DUT(&lt;br /&gt;
    .clock(clock_t),&lt;br /&gt;
    .reset(reset_t),&lt;br /&gt;
    .in(in_t),&lt;br /&gt;
    .out(out_t)&lt;br /&gt;
);&lt;br /&gt;
   &lt;br /&gt;
endmodule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se poate observa ca automatele de tip Moore au un numar mai mare de stari iar automatele de tip Mealy au o logica mai complexa pentru calcularea iesirilor.&lt;br /&gt;
&lt;br /&gt;
==Exerciții==&lt;br /&gt;
=== Exercițiul 1 ===&lt;br /&gt;
Implementați un automat finit ce detectează fronturile descrescătoare. Acesta are un singur semnal de intrare &amp;#039;&amp;#039;in&amp;#039;&amp;#039;, care reprezintă semnalul analizat și o singură ieșire &amp;#039;&amp;#039;out&amp;#039;&amp;#039;, generând pe această un puls lung cât o perioadă de ceas la fiecare apariție a unui front descrescător pe &amp;#039;&amp;#039;in&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Realizați implementarea SystemVerilog plecând de la graful automatului:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Graf FSM falling edge.png]]&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 2 ===&lt;br /&gt;
Implementați un automat finit ce detectează atât fronturile crescătoare, cât și pe cele descrescătoare.&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 3 ===&lt;br /&gt;
Să se implementeze un circuit care generează un semnal PWM cu un factor de umplere ce variază triungular, la fiecare front descrescător al unui semnal de intrare.&lt;br /&gt;
&lt;br /&gt;
Schema circuitului este:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:FSM Exercitiu.png]]&lt;br /&gt;
&lt;br /&gt;
Modulele componente ale circuitului sunt:&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FallingEdgeDetector&amp;#039;&amp;#039;&amp;#039;: Automat ce detectează fronturile descrescătoare ale semnalului de intrare.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TriangularCounter&amp;#039;&amp;#039;&amp;#039;: Automat ce generează la iesire secvența de numere 64, 128, 192, 255, 192, 128, 64.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Counter&amp;#039;&amp;#039;&amp;#039;: Numărător pe 8 biți cu reset sincron.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;COMP&amp;#039;&amp;#039;&amp;#039;: Comparator cu două intrări pe 8 biți. Ieșirea sa va fi 1 atunci când counter &amp;lt; out și 0 în rest.&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 4 ===&lt;br /&gt;
Implementați automatul de control al unui aparat care vinde ciocolata.&lt;br /&gt;
&lt;br /&gt;
O cafea costa 2.5 lei. Automatul accepta monezi de 50 de bani si hartii de 1 leu. Daca se depaseste suma, restul ramane in aparat si va fi folosit la urmatoarea tranzactie. Se accepta introducerea si a unei monezi si a unei bancnote in acelasi timp.&lt;br /&gt;
&lt;br /&gt;
Intrarile sistemului sunt: clock (1b), reset (1b), in_50_b (1b), in_100_b (1b); iesirile sistemului sunt: give_cioco(1b).&lt;br /&gt;
&lt;br /&gt;
Implementati automatul de control care va tine minte suma curenta si va da sau nu ciocolata in functie de aceasta. Implementati acest automat in ambele variante: Mealy si Moore.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_10_:_Aplicatii_cu_numaratoare&amp;diff=7889</id>
		<title>CID aplicatii 10 : Aplicatii cu numaratoare</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_10_:_Aplicatii_cu_numaratoare&amp;diff=7889"/>
		<updated>2024-10-22T13:55:43Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Teorie==&lt;br /&gt;
&lt;br /&gt;
Numaratoarele au extrem de multe aplicatii in lumea reala, cateva dintre acestea fiind descrise mai jos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exemplu: Numaratul apasarilor unui buton==&lt;br /&gt;
	&lt;br /&gt;
Un prim sistem simplu cu numarator poate fi cel care contorizeaza de cate ori a fost apasat un buton sau, echivalent, cate persoane/masini au trecut printr-un senzor, de cate ori a fost deschisa o usa etc. Acest sistem se poate apoi dezvolta cu usurinta pentru a numara si oamenii care trec invers prin respectivul set de senzori prin adaugarea functionalitatii de up/down la numarator.&lt;br /&gt;
&lt;br /&gt;
Un astfel de sistem simplu (varianta doar cu numarat intrari) ar arata in felul urmator: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Aplicatii_numarator_exemplu_contor_senzor.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
Circuitul de debounce are rolul de a &amp;quot;curata&amp;quot; semnalul de intrare, astfel incat chiar si in prezenta zgomotului sau a unei activari indelungate a senzorului/butonului, sa se contorizeze un singur eveniment. O explicatie mai detaliata puteti gasi [[Circuitul_de_debounce|aici]].&lt;br /&gt;
&lt;br /&gt;
Numaratorul numara evenimentele.&lt;br /&gt;
&lt;br /&gt;
Transcodorul pentru display cu 7 segmente este apoi folosit pentru o mai usoara vizualizare a numarului curent. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; transcodorul pentru 7seg din exemplul de mai jos este in logica negativa. Daca circuitul fizic este in logica pozitiva trebuie adaugat un inversor la iesirea din acesta. De asemnea consider segmentul &amp;quot;a&amp;quot; pe bitul &amp;quot;0&amp;quot; si segmentul &amp;quot;h&amp;quot; pe bitul &amp;quot;6&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea debouncer-ului (fisierul debounce.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module debounce&lt;br /&gt;
	#(&lt;br /&gt;
		parameter limit = 20&amp;#039;d650000&lt;br /&gt;
	) (&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic in,&lt;br /&gt;
		output logic out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
logic [19:0] counter; // observatie: si circuitul de debounce foloseste un numarator&lt;br /&gt;
logic hit;&lt;br /&gt;
&lt;br /&gt;
assign out = (counter == limit);&lt;br /&gt;
&lt;br /&gt;
always_ff@(posedge clock) &lt;br /&gt;
begin&lt;br /&gt;
	if(in == 0) &lt;br /&gt;
		begin&lt;br /&gt;
		counter &amp;lt;= 0;&lt;br /&gt;
		hit &amp;lt;= 0;        &lt;br /&gt;
		end &lt;br /&gt;
	else &lt;br /&gt;
		begin&lt;br /&gt;
		if(counter == limit) &lt;br /&gt;
			begin&lt;br /&gt;
			hit &amp;lt;= 1;&lt;br /&gt;
			counter &amp;lt;= counter + 1;&lt;br /&gt;
			end &lt;br /&gt;
		else &lt;br /&gt;
			begin&lt;br /&gt;
			if(in == 1 &amp;amp; hit == 0) &lt;br /&gt;
				begin&lt;br /&gt;
				counter &amp;lt;= counter + 1;&lt;br /&gt;
				end&lt;br /&gt;
			end&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;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea numaratorului pe 4b(fisierul counter_4b.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module counter_4b&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset,&lt;br /&gt;
		input logic en,&lt;br /&gt;
		output logic [3:0] out&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
always_ff@(posedge clock)&lt;br /&gt;
begin&lt;br /&gt;
	if(reset == 1)&lt;br /&gt;
		begin&lt;br /&gt;
		out &amp;lt;=0;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		begin&lt;br /&gt;
		if(en == 1)&lt;br /&gt;
			begin&lt;br /&gt;
			out &amp;lt;= out + 1;&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			begin&lt;br /&gt;
			out &amp;lt;= out;&lt;br /&gt;
			end&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;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea transcodorului pentru afisaj cu 7seg(fisierul transcodor_7seg.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module transcodor_7seg				// logica negativa &lt;br /&gt;
	(&lt;br /&gt;
		input logic [3:0] in,&lt;br /&gt;
  		output logic [6:0] out&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
always_comb&lt;br /&gt;
begin&lt;br /&gt;
	case(in)&lt;br /&gt;
		4&amp;#039;d0: out = 7&amp;#039;b1000000;// h....a&lt;br /&gt;
		4&amp;#039;d1: out = 7&amp;#039;b1111001;&lt;br /&gt;
		4&amp;#039;d2: out = 7&amp;#039;b0100100;&lt;br /&gt;
		4&amp;#039;d3: out = 7&amp;#039;b0110000;&lt;br /&gt;
		4&amp;#039;d4: out = 7&amp;#039;b0011001;&lt;br /&gt;
		4&amp;#039;d5: out = 7&amp;#039;b0010010;&lt;br /&gt;
		4&amp;#039;d6: out = 7&amp;#039;b0000010;&lt;br /&gt;
		4&amp;#039;d7: out = 7&amp;#039;b1111000;&lt;br /&gt;
		4&amp;#039;d8: out = 7&amp;#039;b0000000;&lt;br /&gt;
		4&amp;#039;d9: out = 7&amp;#039;b0010000;&lt;br /&gt;
		4&amp;#039;d10: out = 7&amp;#039;b0001000;&lt;br /&gt;
		4&amp;#039;d11: out = 7&amp;#039;b0000011;&lt;br /&gt;
		4&amp;#039;d12: out = 7&amp;#039;b1000110;&lt;br /&gt;
		4&amp;#039;d13: out = 7&amp;#039;b0100001;&lt;br /&gt;
		4&amp;#039;d14: out = 7&amp;#039;b0000110;&lt;br /&gt;
		4&amp;#039;d15: out = 7&amp;#039;b0001110;&lt;br /&gt;
		default: out = 7&amp;#039;b1111111;//tot stins &lt;br /&gt;
	endcase &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;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea sistemului, modulul de top (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset,&lt;br /&gt;
		input logic button,&lt;br /&gt;
		output logic [6:0] out    // logica negativa &lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic debounce_0_X_out;&lt;br /&gt;
logic [3:0] counter_4b_0_X_out;   &lt;br /&gt;
    &lt;br /&gt;
debounce&lt;br /&gt;
	#(&lt;br /&gt;
		.limit(20&amp;#039;d50_000)&lt;br /&gt;
	) debounce_0 (&lt;br /&gt;
		.clock(clock),&lt;br /&gt;
		.in(button),&lt;br /&gt;
		.out(debounce_0_X_out)&lt;br /&gt;
	);&lt;br /&gt;
	    &lt;br /&gt;
counter_4b counter_4b_0&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock),&lt;br /&gt;
		.reset(reset),&lt;br /&gt;
		.en(debounce_0_X_out),&lt;br /&gt;
		.out(counter_4b_0_X_out)&lt;br /&gt;
    );    &lt;br /&gt;
    &lt;br /&gt;
transcodor_7seg	transcodor_7seg_0			// logica negativa &lt;br /&gt;
	(&lt;br /&gt;
		.in(counter_4b_0_X_out),&lt;br /&gt;
  		.out(out)&lt;br /&gt;
    );    &lt;br /&gt;
 &lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea test bench-ului(fisierul tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module tb();&lt;br /&gt;
&lt;br /&gt;
logic clock_tb;&lt;br /&gt;
logic reset_tb;&lt;br /&gt;
logic button_tb;&lt;br /&gt;
logic [6:0] out_tb;&lt;br /&gt;
&lt;br /&gt;
top dut&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock_tb),&lt;br /&gt;
		.reset(reset_tb),&lt;br /&gt;
		.button(button_tb),&lt;br /&gt;
		.out(out_tb)    // logica negativa &lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	clock_tb = 0;&lt;br /&gt;
	forever&lt;br /&gt;
		begin&lt;br /&gt;
		#5 clock_tb = ~clock_tb;&lt;br /&gt;
		end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	reset_tb = 0;&lt;br /&gt;
	button_tb = 0;&lt;br /&gt;
	&lt;br /&gt;
	#50;&lt;br /&gt;
	reset_tb = 1;&lt;br /&gt;
	#50;&lt;br /&gt;
	reset_tb = 0;&lt;br /&gt;
	#100;&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) 	// vreau 5 apasari de buton&lt;br /&gt;
		begin&lt;br /&gt;
		button_tb = 1;&lt;br /&gt;
		repeat(70_000)				&lt;br /&gt;
			begin&lt;br /&gt;
			@(posedge clock_tb);&lt;br /&gt;
			end&lt;br /&gt;
		button_tb = 0;&lt;br /&gt;
		repeat(70_000)&lt;br /&gt;
			begin&lt;br /&gt;
			@(posedge clock_tb);&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
	#1000 $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;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
=== Exercitiul 1: Divizor de frecventa cu puteri ale lui 2=== &lt;br /&gt;
&lt;br /&gt;
Divizorul de frecventa are rolul de a genera un semnal de ceas mai lent din semnalul de ceas principal. &lt;br /&gt;
El este alcatuit doar dintr-un numarator, iar fiecare bit al acestuia va fi practic un semnal de ceas cu frecventa din ce in ce mai mica astfel (la jumate): &lt;br /&gt;
&lt;br /&gt;
bit[0] - frecventa de 2 ori mai mica decat semnalul de ceas&lt;br /&gt;
 &lt;br /&gt;
bit[1] - frecventa de 2 ori mai mica decat bit[0], deci de 4 ori mai mica decat semnalul de ceas &lt;br /&gt;
&lt;br /&gt;
bit[2] - frecventa de 2 ori mai mica decat bit[1], deci de 8 ori mai mica decat semnalul de ceas &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Acest lucru se poate observa si in poza ce urmeaza: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Freq_divider_output.png| 800px]] &lt;br /&gt;
&lt;br /&gt;
Implementati acest circuit, si folosind ledurile prezente pe placa, incercati sa conectati bitul corespunzator la leduri astfel incat cel mai din dreapta led sa clipeasca cu o frecventa cat mai apropiata de 1s. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Printr-un astfel de divizor de frecventa minimal, un numar foarte mic de frecvente poate fi generat. Daca se doreste generarea unui semnal periodic cu o perioada exacta, diferita de cele posibile prin acest mecanism, se poate construi urmatorul circuit:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: Divizor de frecventa ce poate genera orice perioada=== &lt;br /&gt;
&lt;br /&gt;
Un astfel de divizor de frecventa este construit ca in figura de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Freq_div_orice_freq.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
Prin adaugarea constantei &amp;quot;limit&amp;quot;, perioada semnalului de iesire poate sa fie orice multiplu a perioadei semnalului de ceas. &lt;br /&gt;
&lt;br /&gt;
Bistabilul de tip t, se modifica atunci cand limita este atinsa si practic iesirea lui este semnalul periodic dorit (cu observatia ca o perioada a semnalului de iesire necesita 2 numarari pana la limita).&lt;br /&gt;
&lt;br /&gt;
Sa se calculeze valoarea necesara pentru &amp;quot;limit&amp;quot; astfel incat pe leduri sa se genereze semnal cu perioada exact 1s.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; In FPGA exista fizic trasee speciale pentru reset si ca sinteza sa le foloseasca pe acestea in mod optim nu este recomandat sa se puna logica (cum e aici poarta sau) pe acestea. Modificati schema de mai sus astfel incat sa eliminati respectiva poarta de pe reset. (Sfat: numaratorul va avea acum si intrari de load: semnalul de comanda si data propriu zisa)&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: PWM (Pulse Width Modulation)===&lt;br /&gt;
&lt;br /&gt;
PWM este un concept folosit foarte des in multiple ramuri ale ingineriei, de la transmisiunea informatiei pana la controlul motoarelor sau al intensitatii ledurilor din instalatii de Craciun. El se refera la a avea un semnal periodic cu factor de umplere variabil, asa cum este aratat in poza de mai jos :&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm.png| 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generarea unui astfel de semnal periodic se face printr-un numarator si un comparator, ca in figura de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm_schematic.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Raportul dintre limita pusa si valoarea la care numaratorul se reseteaza este practic factorul de umplere selectat.&lt;br /&gt;
&lt;br /&gt;
Pentru testare pe placa, cei 6b ai limitei provin de la switch-uri si butoane. Afisarea se face pe led[0].&lt;br /&gt;
&lt;br /&gt;
Testati acest circuit in simulare si apoi implementati pe placa pentru o valoare fixa a limitei. Implementati in paralel mai multe generatoare de semnal PWM cu limite diferite, astfel incat sa observati diferentele de intentistate dintre ledurile comandate de acestea.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: PWM cu limita variabila===&lt;br /&gt;
&lt;br /&gt;
Un exemplu foarte uzual de folosire a PWM este aprinderea ledurilor cu diverse pattern-uri. Factorul de umplere determina intensitatea cu care ledul este aprins. Un PWM cu o limita variabila automata va face ledul sa para din ce in ce mai stins sau din ce in ce mai luminos (exemplu: instalatii de Craciun). Combinand asta cu leduri RGB se obtin efecte de schimbare a culorii ledului aparent la intamplare. &lt;br /&gt;
&lt;br /&gt;
Un astfel de circuit se realizeaza punand inca un numarator in locul limitei, ca in poza de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm_duty_cycle_up_schematic.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru o functionalitate suplimentara, anume a pastra un anumit factor de umplere mai multe perioade, am adaugat inca un numarator.&lt;br /&gt;
&lt;br /&gt;
Pentru claritatea desenului, nu am mai tras efectiv firul de ceas catre intrarile unde acesta se duce.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rezultatul este: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Pwm_duty_cycle_up_output.png | 800px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Testati circuitul propus prin simulare si apoi vizualizati implementarea sa pe placa. Alegeti limite potrivite astfel incat sa puteti observa usor rezultatul.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Bonus:&amp;#039;&amp;#039;&amp;#039; Incercati sa adaugati si parametri pentru LIMIT_DUTY_CYCLE_LOW si LIMIT_DUTY_CYCLE_HIGH, care sa permita factorului de umplere sa varieze doar intre ele (numaratorul va avea nevoie de intrari pentru comanda de load si data load, ca sa poata incepe de la orice valoare).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Bonus:&amp;#039;&amp;#039;&amp;#039; Modificati circuitul astfel incat semnalul de iesire sa isi schimbe sensul de variatie al factorului de umplere cand ajunge cu acesta la capat. In forma curenta factorul de umplere creste de la 0% la 100% si apoi se reseteaza brusc la 0%, repetand acest ciclu. Se vrea ca la ajungerea la 100% sa inceapa o scadere treptata catre 0%, urmata apoi de o urcare s.a.m.d.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Ceas===&lt;br /&gt;
&lt;br /&gt;
Un ceas poate fi construit cifra cu cifra, folosind numaratoare si comparatoare (si transcodoare pentru display cu 7seg ca sa se vada totul mai bine pe placa).&lt;br /&gt;
&lt;br /&gt;
Incercati sa implementati un ceas cu milisecunde, secunde si minute in varianta comportamentala. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Va fi nevoie fie separat, fie in modul de un numarator cu frecventa rezolutiei dorite (aici 1 ms).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Codul va contine multe &amp;quot;if&amp;quot; de tipul &amp;quot;daca cifra unitatilor secundelor a ajuns la 10, se face 0 si cresc cifra zecilor&amp;quot;, repetate pentru fiecare cifra.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Incercati si o implementare structurala a ceasului, mergand pe aceeasi idee. Fiecare cifra va contine numaratorul ei. Cand numaratorul unei cifre ajunge ajunge la limita sa, va da enable pentru numaratorul cifrei urmatoare. Daca este nevoie se pot folosi si porti aditionale (ex: ca sa creasca minutul cifra zecilor secundelor trebuie sa fie 5 si cifra unitatilor secundelor trebuie sa fie 9). &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Va fi nevoie de un numarator cu frecventa rezolutiei dorite (aici 1 ms sau 1s).&lt;br /&gt;
 &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Pentru a scrie mai putin puteti face un numarator doar cu secunde si minute. Principiul de baza este acelasi si daca aveati milisecunde.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Simularea a cateva milisecunde sau chiar secunde este un proces indelungat (dureaza minute-ore fizice), astfel strict pentru simulari se recomanda ceasul sa functioneze cu microsecunde sau milisecunde maxim.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_8_:_Registre_si_memorii_RAM&amp;diff=7888</id>
		<title>CID aplicatii 8 : Registre si memorii RAM</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_8_:_Registre_si_memorii_RAM&amp;diff=7888"/>
		<updated>2024-10-22T13:55:06Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are scopul de a prezenta circuitele secventiale simple: registre si memorii RAM. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pornind de la bistabilii prezentati/construiti in laboratorul anterior, apare notiunea de registru, acesta fiind o grupare de bistabili. Astfel in loc sa se memoreze un singur bit de informatie (bistabil), se pot memora acum numere pe mai multi biti (registru).&lt;br /&gt;
&lt;br /&gt;
Din exterior, un registru este vazut astfel: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Registru_exterior_view.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Semnalul de &amp;quot;clock&amp;quot; controleaza sincronizarea registrilor din tot sistemul.&lt;br /&gt;
:Semnalul de &amp;quot;reset&amp;quot; aduce registrul la o valoare initiala (uzual 0).&lt;br /&gt;
:Semnalul de &amp;quot;we&amp;quot; (write enable) controleaza salvarea unor date noi. Cand acesta este activ, data de pe intrarea &amp;quot;data_in&amp;quot; se salveaza in registru.&lt;br /&gt;
:Semnalul &amp;quot;data_in&amp;quot; reprezinta datele ce se doresc a fi scrise in registru.&lt;br /&gt;
:Semnalul &amp;quot;data_out&amp;quot; reprezinta valoarea stocata in registru.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Semnalele &amp;quot;data_in&amp;quot; si &amp;quot;data_out&amp;quot; pot fi pe oricat de multi biti se doreste, in mod uzual multipli de 8.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pornind de la notiunea de registru (care poate fi vazut ca o memorie cu o locatie si avand &amp;quot;m&amp;quot; biti) se doreste cresterea acestei memorii astfel incat aceasta sa curpinda mai multe locatii adresabile, unde se pot stoca date. Adaugand mai multi registri in paralel, unul langa altul, si cateva circuite de tip mux/demux se poate obtine o memorie de tip RAM (Random Access Memory), cu &amp;quot;m&amp;quot; locatii de &amp;quot;n&amp;quot; biti fiecare. Aceste memorii se cheama &amp;quot;Random Access&amp;quot; deoarece permit si scriere si citire. In functie de tehologia folosita, memoriile RAM pot fi construite din bistabili sau din latch-uri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Din exterior, o memorie RAM este vazuta astfel: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Ram_mXn_1read_1write_exterior_view.png ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Semnalele acestui circuit se pot imparti in semnale ce tin de interfata de scriere sau interfata de citire si mai apoi in semnale de date si semnale de control. Interfata sa este: &lt;br /&gt;
	&lt;br /&gt;
:Semnalul de &amp;quot;clock&amp;quot;: controleaza sincronizarea registrilor din memorie.&lt;br /&gt;
:Semnalul &amp;quot;addr_read&amp;quot;: adresa de la care se citesc datele. &lt;br /&gt;
:Semnalul &amp;quot;data_read&amp;quot;: data ce se citeste.&lt;br /&gt;
:Semnalul de &amp;quot;we&amp;quot;: semnal de control ce controleaza activarea scrierii. Scrierea are loc doar cand acest semnal este activ.&lt;br /&gt;
:Semnalul &amp;quot;addr_write&amp;quot;: adresa la care se scriu datele.&lt;br /&gt;
:Semnalul &amp;quot;data_write&amp;quot;: data ce urmeaza a fi scrisa atunci cand semnalul &amp;quot;we&amp;quot; este activ.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Orice memorie are &amp;quot;m&amp;quot; locatii de &amp;quot;n&amp;quot; biti. Semnalele de &amp;quot;data_read&amp;quot; si &amp;quot;data_write&amp;quot; au aceeasi dimensiune, &amp;quot;n&amp;quot;, numarul de biti ai fiecarei locatii. Semnalele de adresa au dimensiunea log2(m). Pentru o memorie cu 16 locatii va fi nevoie de 4 biti de adresa pentru a putea selecta orice locatie, pentru 32 locatii 5b s.a.m.d. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: In unele situatii se mai poate pune un registru suplimentar pe iesirea datelor, cu rol in sincronizare si evitarea timpilor de propagare prea lungi intre elemente de memorare (ajuta implementarea conceptului de pipeline).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Exista mai multe variante de memorii RAM (cu registru pe iesire/fara, multiport/single port citire, adrese separate sau nu pentru citire/scriere). Cea de mai sus este o memorie cu un singur port de citire, fara registru suplimentar pe iesire, ce foloseste adrese distincte pentru citire si pentru scriere (la fel de bine se poate lucra si cu o singura adresa, comuna pentru scriere si citire).&lt;br /&gt;
 &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Memoriile RAM pot sa nu aiba reset, utilizatorul trebuie apoi sa aiba grija sa citeasca doar din locatii scrise de el anterior.&lt;br /&gt;
In mod uzual ele nu au reset.&lt;br /&gt;
&lt;br /&gt;
==Exemple==&lt;br /&gt;
&lt;br /&gt;
===Exemplul 1 : Registrul===&lt;br /&gt;
&lt;br /&gt;
In urmatorul exemplu se implementeaza registrul descris mai sus:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea registrului (fisierul register_8b.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module register_8b&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset, // activ pe &amp;quot;1&amp;quot;&lt;br /&gt;
		input logic we,&lt;br /&gt;
		input logic [7:0] data_in, &lt;br /&gt;
		output logic [7:0] data_out // data_out are aceeasi dimensiune ca data_in&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
always_ff@(posedge clock) // clock sincronizeaza actiunile circuitului&lt;br /&gt;
begin    // doar pe edge-ul pozitiv circuitul actioneaza&lt;br /&gt;
    if(reset == 1)&lt;br /&gt;
    	begin&lt;br /&gt;
    	data_out &amp;lt;= 0;&lt;br /&gt;
    	end&lt;br /&gt;
    else&lt;br /&gt;
    	begin&lt;br /&gt;
		if(we == 1) // comanda de scriere&lt;br /&gt;
			begin&lt;br /&gt;
			data_out &amp;lt;= data_in;&lt;br /&gt;
			end&lt;br /&gt;
		else // puteam sa omit acest else&lt;br /&gt;
			begin&lt;br /&gt;
			data_out &amp;lt;= data_out; // raman datele salvate anterior&lt;br /&gt;
			end&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;
&lt;br /&gt;
Un alt mod de a scrie un registru este dat mai jos, cu observatia ca aici am pus semnalul de reset activ in logica negativa:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea registrului (fisierul register_8b_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module register_8b_v2&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		input logic reset_n, // activ in &amp;quot;0&amp;quot;&lt;br /&gt;
		// uzual semnalel cu n in fata sau la sfarsit sunt in logica negativa: nreset, resetn&lt;br /&gt;
		input logic we,&lt;br /&gt;
		input logic [7:0] data_in,&lt;br /&gt;
		output logic [7:0] data_out&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
logic [7:0] memorie_efectiva;   &lt;br /&gt;
&lt;br /&gt;
assign data_out = memorie_efectiva;&lt;br /&gt;
    &lt;br /&gt;
always_ff@(posedge clock)&lt;br /&gt;
begin  &lt;br /&gt;
	if( reset_n == 0) &lt;br /&gt;
		begin&lt;br /&gt;
		memorie_efectiva &amp;lt;= 0;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		begin&lt;br /&gt;
		if(we == 1)&lt;br /&gt;
			begin&lt;br /&gt;
			memorie_efectiva &amp;lt;= data_in;&lt;br /&gt;
			end&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;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea test bench-ului registrului pe 8biti: (fisierul register_8b_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module register_8b_tb();&lt;br /&gt;
&lt;br /&gt;
logic clock_tb;&lt;br /&gt;
logic reset_tb;&lt;br /&gt;
logic we_tb;&lt;br /&gt;
logic [7:0] data_in_tb;&lt;br /&gt;
logic [7:0] data_out_tb;&lt;br /&gt;
&lt;br /&gt;
register_8b dut 	// varianta cu reset activ in &amp;quot;1&amp;quot;&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock_tb),&lt;br /&gt;
		.reset(reset_tb),&lt;br /&gt;
		.we(we_tb),&lt;br /&gt;
		.data_in(data_in_tb),&lt;br /&gt;
		.data_out(data_out_tb)&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	clock_tb = 0;&lt;br /&gt;
	forever &lt;br /&gt;
		begin&lt;br /&gt;
		#5 clock_tb = ~clock_tb; // perioada totala 10 !!!&lt;br /&gt;
		end&lt;br /&gt;
end    &lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	reset_tb &amp;lt;= 0;&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	data_in_tb &amp;lt;= 0;&lt;br /&gt;
		// observatie: pana la primul reset sau prima scriere, valoarea din registru va fi necunoscuta (in simulare X)&lt;br /&gt;
		&lt;br /&gt;
		// dau reset la circuit&lt;br /&gt;
	@(posedge clock_tb); // astept sa treaca 1 clock cycle&lt;br /&gt;
	reset_tb &amp;lt;= 1;	&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	reset_tb &amp;lt;= 0;&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		// incep sa fac scrieri&lt;br /&gt;
	we_tb &amp;lt;= 1;&lt;br /&gt;
	data_in_tb &amp;lt;= 5;&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	data_in_tb &amp;lt;= 10;	// scrierea asta nu se face deoarece nu am write enable activ&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_in_tb &amp;lt;= 11;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_in_tb &amp;lt;= 12;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb = 1;&lt;br /&gt;
	data_in_tb &amp;lt;= 42;	// asta da&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_in_tb &amp;lt;= 51;	// si asta da&lt;br /&gt;
	@(posedge clock_tb);	&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&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;
&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Memorie RAM===&lt;br /&gt;
	&lt;br /&gt;
In urmatorul exemplu se implementeaza memoria RAM descrisa mai sus, particularizata pentru 64 de locatii a cate 8b fiecare:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea memoriei RAM: (fisierul ram64x8_v1.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module ram64x8_v1&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		//interfata de citire&lt;br /&gt;
			input logic [5:0] addr_read, // 64 locatii =&amp;gt; 6 biti de adresa &lt;br /&gt;
			output logic [7:0] data_read, // fiecare locatie are 8b  &lt;br /&gt;
		// interfata de scriere&lt;br /&gt;
			input logic we,&lt;br /&gt;
			input logic [5:0] addr_write,&lt;br /&gt;
			input logic [7:0] data_write&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic [7:0] memorie_efectiva [0:63]; // memorie cu locatiile de la 0 la 63, fiecare avand 8 biti    &lt;br /&gt;
&lt;br /&gt;
assign data_read = memorie_efectiva[addr_read]; // fara registru pe iesire =&amp;gt; citire asincrona fata de clock &lt;br /&gt;
    &lt;br /&gt;
always_ff@(posedge clock)&lt;br /&gt;
begin    &lt;br /&gt;
    if(we == 1)&lt;br /&gt;
    	begin&lt;br /&gt;
    	memorie_efectiva[addr_write] &amp;lt;= data_write; // scriu la locatia data de &amp;quot;addr_write&amp;quot; din memoria efectiva datele &amp;quot;data_write&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;
Acesta va fi folosit si pe post de modul de &amp;quot;top&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Echivalent se poate folosi si sintaxa cu always ca mai jos.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea memoriei RAM: (fisierul ram64x8_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module ram64x8_v2 // varianta cu always combinational pe citire&lt;br /&gt;
	(&lt;br /&gt;
		input logic clock,&lt;br /&gt;
		//interfata de citire&lt;br /&gt;
			input logic [5:0] addr_read,&lt;br /&gt;
			output logic [7:0] data_read,&lt;br /&gt;
		// interfata de scriere&lt;br /&gt;
			input logic we,&lt;br /&gt;
			input logic [5:0] addr_write,&lt;br /&gt;
			input logic [7:0] data_write&lt;br /&gt;
    );&lt;br /&gt;
    &lt;br /&gt;
logic [7:0] memorie_efectiva [0:63];  &lt;br /&gt;
&lt;br /&gt;
always_comb //  citire asincrona fata de clock &lt;br /&gt;
begin&lt;br /&gt;
	data_read = memorie_efectiva[addr_read]; &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
always_ff@(posedge clock)&lt;br /&gt;
begin    &lt;br /&gt;
    if(we == 1)&lt;br /&gt;
    	begin&lt;br /&gt;
    	memorie_efectiva[addr_write] &amp;lt;= data_write; // scriu la locatia data de &amp;quot;addr_write&amp;quot; din memoria efectiva datele &amp;quot;data_write&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;
&amp;#039;&amp;#039;&amp;#039;Descrierea test bench-ului memoriei RAM: (fisierul ram64x8_v1_tb.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns / 1ps&lt;br /&gt;
&lt;br /&gt;
module ram64x8_tb();&lt;br /&gt;
&lt;br /&gt;
logic clock_tb;&lt;br /&gt;
logic [5:0] addr_read_tb;&lt;br /&gt;
logic [7:0] data_read_tb;&lt;br /&gt;
logic we_tb;&lt;br /&gt;
logic [5:0] addr_write_tb;&lt;br /&gt;
logic [7:0] data_write_tb;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ram64x8_v1 dut&lt;br /&gt;
	(&lt;br /&gt;
		.clock(clock_tb),&lt;br /&gt;
		//interfata de citire&lt;br /&gt;
			.addr_read(addr_read_tb), // 64 locatii =&amp;gt; 6 biti de adresa &lt;br /&gt;
			.data_read(data_read_tb), // fiecare locatie are 8b  &lt;br /&gt;
		// interfata de scriere&lt;br /&gt;
			.we(we_tb),&lt;br /&gt;
			.addr_write(addr_write_tb),&lt;br /&gt;
			.data_write(data_write_tb)&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	clock_tb = 0;&lt;br /&gt;
	forever &lt;br /&gt;
		begin&lt;br /&gt;
		#5 clock_tb = ~clock_tb; // perioada totala 10 !!!&lt;br /&gt;
		end&lt;br /&gt;
end    &lt;br /&gt;
&lt;br /&gt;
initial&lt;br /&gt;
begin&lt;br /&gt;
	we_tb &amp;lt;= 0;&lt;br /&gt;
	data_write_tb &amp;lt;= 0;&lt;br /&gt;
	addr_read_tb &amp;lt;= 0; // citind de la o adresa nescrisa inca, iesirea e necunoscuta&lt;br /&gt;
	addr_write_tb &amp;lt;= 0;&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		// incep sa fac scrieri&lt;br /&gt;
	we_tb &amp;lt;= 1;	// scriu data 5 la adresa 10&lt;br /&gt;
	addr_write_tb &amp;lt;= 10;&lt;br /&gt;
	data_write_tb &amp;lt;= 5;&lt;br /&gt;
	addr_read_tb &amp;lt;= 11; // citind de la o adresa nescrisa inca, iesirea e necunoscuta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb &amp;lt;= 0;			// scrierea asta nu se face deoarece nu am write enable activ	&lt;br /&gt;
	addr_write_tb &amp;lt;= 11;&lt;br /&gt;
	data_write_tb &amp;lt;= 10;	&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_write_tb &amp;lt;= 11;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_write_tb &amp;lt;= 12;	// nici asta&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	we_tb &amp;lt;= 1;&lt;br /&gt;
	addr_write_tb &amp;lt;= 20; // scriere ok &lt;br /&gt;
	data_write_tb &amp;lt;= 42;	// scriu data 42 la adresa 20&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	data_write_tb &amp;lt;= 51;	// si asta; suprascriu datele anterioare la adresa 20.&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	addr_write_tb &amp;lt;= 21;&lt;br /&gt;
	data_write_tb &amp;lt;= 11;	// scriere ok&lt;br /&gt;
	addr_read_tb &amp;lt;= 20; // citesc de la adresa 20, scrisa anteior deci voi vedea date cunoscute pe iesire.&lt;br /&gt;
	@(posedge clock_tb);&lt;br /&gt;
	addr_write_tb &amp;lt;= 23;&lt;br /&gt;
	data_write_tb &amp;lt;= 14;	// scriere ok &lt;br /&gt;
	addr_read_tb &amp;lt;= 21; // variez adresa de citire si pot parcurge memorie locatie cu locatie&lt;br /&gt;
	@(posedge clock_tb);	&lt;br /&gt;
	we_tb &amp;lt;= 0;	// opresc scrierea&lt;br /&gt;
	&lt;br /&gt;
	repeat(5) // dupa 5 cicli de ceas&lt;br /&gt;
		begin&lt;br /&gt;
		@(posedge clock_tb);&lt;br /&gt;
		end&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;
[[Fișier:Ram64X8_waveform.png|1000px]]&lt;br /&gt;
&lt;br /&gt;
In forma de unda de mai sus sunt marcate momentele de timp cand au loc scrieri in memorie (cand am write enable activ si valori cunoscute pentru data si adresa de scriere). Se salveaza valorile imediat la stanga frontului de ceas.&lt;br /&gt;
&lt;br /&gt;
In simularea completa, se poate observa si scrierea in registrii din memorie a datelor dorite  la adresa setata.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
===Exercitiul 1: RAM cu registru la iesire=== &lt;br /&gt;
&lt;br /&gt;
Pornind de la exemplul anterior, se doreste adaugarea unui registru la citirea datelor, astfel citirea devenind sincrona cu semnalul de ceas. In cod acest lucru se poate face foarte usor, punand operatia de citire pe ceas.&lt;br /&gt;
&lt;br /&gt;
Se doreste simularea si apoi testarea fizica a acestei memorii. Simularea noii memorii se face prin executarea a 3 scrieri la adrese diferite si citirea apoi a datelor respective. Sinteza si testarea fizica necesita micsorarea memoriei din cauza numarului limitat de switchuri/butoane al placii. Vom lucra acum cu o memorie de 8 locatii X 4 biti. &lt;br /&gt;
Adresa va fi comandata de switch-uri si datele de intrare din butoane. Se va folosi Button[0] pentru semnalul de &amp;quot;we&amp;quot; (write enable). Afisarea datelor se va face pe leduri.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: RAM multiport citire===&lt;br /&gt;
&lt;br /&gt;
Pornind de la exercitiul 1, se doreste modificarea memoriei astfel incat sa poata fi citite 2 locatii simultan si independent de adresa la care se face scrierea. Se pastreaza citirea sincrona.&lt;br /&gt;
&lt;br /&gt;
Se obtine astfel un circuit a carui interfata este la randul ei compusa din 3 interfete (+semnal comun &amp;quot;clock&amp;quot;): &lt;br /&gt;
&lt;br /&gt;
:- interfata de scriere &lt;br /&gt;
&lt;br /&gt;
:- interfata de citire 0&lt;br /&gt;
&lt;br /&gt;
:- interfata de citire 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Interfata circuitului arata ca in figura de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Ram_64X8_2read_1write_exterior_view.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda corespunzatoare pentru a testa aceasta memorie.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie&amp;#039;&amp;#039;&amp;#039;: Blocul de registri (register file) din interiorul procesoarelor (vedeti AMP) poate fi o astfel de memorie RAM. Are 2 adrese pentru citirea celor 2 operanzi care intra in ALU si o adresa pentru rezultatul calculului ce este salvat.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Registrul paralel-serie===&lt;br /&gt;
&lt;br /&gt;
Descrieti comportamental un registru paralel-serie. Acesta are rolul de a salva datele de la intrare pe &amp;quot;n&amp;quot; biti (aici 8) si apoi de a le scoate la iesire bit cu bit.&lt;br /&gt;
&lt;br /&gt;
Interfata acestuia este data in desenul de mai jos. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Registru_paralel_serie.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Semnalul de &amp;quot;en&amp;quot; (enable) are rolul de a controla deplasarea, care se executa prin operatia de shiftare la dreapta &amp;quot;&amp;gt;&amp;gt;&amp;quot;. Daca acesta are valoarea &amp;quot;1&amp;quot;, datele salvate se muta la dreapta cu o pozitie.&lt;br /&gt;
:Semnalul de write_en/start/save are rolul de a salva cei 8 biti care urmeaza a fi serializati.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda corespunzatoare pentru a testa aceast circuit (minim 3 scrieri/serializari).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Bonus&amp;#039;&amp;#039;&amp;#039;: Realizati acelasi circuit folosind o descriere structurala.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Registrul serie-paralel===&lt;br /&gt;
&lt;br /&gt;
Descrieti comportamental un registru serie-paralel. Acesta are rolul de a salva date introduse bit cu bit ca apoi sa fie scoase cate &amp;quot;n&amp;quot; biti deodata.&lt;br /&gt;
&lt;br /&gt;
Interfata acestuia este data in desenul de mai jos. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Registru_serie_paralel.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
Semnalul de &amp;quot;en&amp;quot; (enable) are rolul de a controla deplasarea, care se executa prin operatia de shiftare la dreapta &amp;quot;&amp;gt;&amp;gt;&amp;quot;. Daca acesta are valoarea &amp;quot;1&amp;quot;, datele salvate se muta la dreapta cu o pozitie.&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda corespunzatoare pentru a testa aceast circuit (minim 3 scrieri/paralelizari).&lt;br /&gt;
&lt;br /&gt;
Citirea se poate face oricand, desi doar dupa &amp;quot;n&amp;quot; pasi, va fi cu valoarea corecta.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Registrul de intarziere pe 8b===&lt;br /&gt;
&lt;br /&gt;
Prin conectarea in serie a mai multor registri pe 8b (astfel incat data ce iese din unul sa fie intrare pentru urmatorul) se pot construi registri de intarziere cu &amp;quot;x&amp;quot; cicli de ceas. Cum fiecare registru salveaza datele pe ceas, se poate spune ca datele de la iesire sunt intarziate cu un ceas fata de datele de la intrare, astfel o intarziere cu &amp;quot;x&amp;quot; cicli de ceas se obtine prin punerea in serie a &amp;quot;x&amp;quot; registri. &lt;br /&gt;
&lt;br /&gt;
Pornind de la un registru simplu pe 8b (exemplul 1), construiti structural un registru de intarziere cu 4 cicli de ceas. &lt;br /&gt;
&lt;br /&gt;
Testati functionarea acestuia prin simulare. Datale introduse trebuie sa iasa defazate cu 4 cicli de ceas (adica cu 4 cicli de ceas mai tarziu).&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=7887</id>
		<title>CID aplicatii 5 : Exercitii cu circuite combinationale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=7887"/>
		<updated>2024-10-22T13:54:30Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostiintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 1 in anii anteriori si cateva notiuni de teorie si sintaxa ajutatoare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: Parametrizare==&lt;br /&gt;
Parametrizarea este un mod de a generaliza codul scris pentru a nu fi nevoie sa scrii acelasi modul de mai multe ori doar pentru ca circuitul isi schimba o dimensiune. &lt;br /&gt;
&lt;br /&gt;
Pentru a intelege mai clar avantajele si sintaxa urmariti urmatorul exemplu:&lt;br /&gt;
&lt;br /&gt;
Fisierul sumator.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator # // &amp;lt;= diez deoarece urmeaza lista cu paramteri&lt;br /&gt;
				( // parametri &lt;br /&gt;
					parameter data_size = 4 // valoare default 4&lt;br /&gt;
					// alti parametri aici daca este nevoie, separati prin virgula&lt;br /&gt;
				)&lt;br /&gt;
				( // interfata &lt;br /&gt;
					input logic [data_size-1:0] in0, // si pot folosii parametrul &amp;quot;data_size&amp;quot; pentru dimensiunea bus-ului&lt;br /&gt;
					input logic [data_size-1:0] in1,&lt;br /&gt;
					output logic [data_size-1:0] out0&lt;br /&gt;
				);&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 + in1;				&lt;br /&gt;
				&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cand se instantiaza un modul parametrizat, se specifica valorile parametrilor astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(8)   // se genereaza un sumator pe 8b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_0&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out0)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(32)  // se genereaza un sumator pe 32b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_1&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator nume_instanta_2 // se genereaza un sumator de dimensiune default, aici 4, asa cum e scris in modulul &amp;quot;sumator&amp;quot;&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out2)&lt;br /&gt;
	);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puteti folosi parametrizarea in exercitiul 3 de mai jos. Acolo sunt 2 tipuri de multiplexoare, unul cu intrarile pe 1 bit si unul cu intrarile pe 2 biti. Poate fi scris un singur modul parametrizat care sa acopere ambele situatii.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Concatenarea==&lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara conectare a firelor sau pentru o mai buna organizare si expresivitate a codului, de multe ori este util ca fire individuale sa fie grupate impreuna sau ca un bus de mai multi biti sa fie separat in fire individuale. Acest lucru se face folosind concatenarea, prin simbolurile &amp;quot;{ }&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Un exemplu de folosire a concatenarii este oferit mai jos.&lt;br /&gt;
Un sumator pe 8b are rezultatul pe maxim 9b, in cazul in care ambele numere sunt mari. Astfel apare un bit de carry out. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator ( &lt;br /&gt;
            input logic [7:0] in0,&lt;br /&gt;
            input logic [7:0] in1,&lt;br /&gt;
            output logic [7:0] out0,&lt;br /&gt;
            output logic carry_out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign {carry_out,out0} = in0 + in1; // fac suma intre in0 si in1 iar rezultatul il pun pe cei 9b alcatuiti din: 1b carry_out si 8b out0, in ordinea asta&lt;br /&gt;
&lt;br /&gt;
endmodule       &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Se pot concatena oricat de multe semnale, puse in &amp;quot;{ }&amp;quot; si separate prin virgula. Atentie la dimensiunile firelor care se concateneaza.&lt;br /&gt;
&lt;br /&gt;
Se poate de asemenea face concatenare si la dreapta egalului, astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fir_pe_10_b = {fir_pe_3b,fir_pe_5b,fir_pe_1b,fir_pe_1b};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In exemplul anterior ultimi 2b ai &amp;quot;fir_pe_10_b&amp;quot; vor avea mereu aceeasi valoare, provenind din acelasi fir. Sintaxa SystemVerilog permite asta.&lt;br /&gt;
&lt;br /&gt;
Puteti folosii concatenarea, in exercitiul 2, la flag-ul de overflow.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Constante ca intrari in circuite==&lt;br /&gt;
In cazul in care se doreste scrierea unor constante la intrarea unor module, acestea se pun direct intre paranteze la instantiere. &lt;br /&gt;
De exemplu, pentru multiplexorul de jos din subiectul &amp;quot;alu structural&amp;quot;, intrarea &amp;quot;in3&amp;quot; este conectata la valoarea &amp;quot;1&amp;quot;. Sintaxa pentru aceasta este: &amp;quot;.in3(1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: &amp;quot;_&amp;quot;==&lt;br /&gt;
Simbolul &amp;quot;_&amp;quot; (underscore) este ignorat de SystemVerilog si ajuta vizual la citirea semnalelor pe mai multi biti. De exemplu 16&amp;#039;b1010010111110000 este identic cu 16&amp;#039;b1010_0101_1111_0000, al doilea fiind totusi mai usor de citit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
===Exercitiul 1: ALU - descriere comportamentala===&lt;br /&gt;
Descrieți comportamental o unitate aritmetico-logică (ALU) care are la intrare 2 numere binare de câte 8 biți și poate calcula următoarele funcții:&lt;br /&gt;
:- suma celor două numere&lt;br /&gt;
:- diferența celor două numere&lt;br /&gt;
:- operații logice bit cu bit (bitwise): SI, SAU, XOR și inversele lor&lt;br /&gt;
:- operandul din stanga trece neschimbat&lt;br /&gt;
:- operandul din dreapta trece neschimbat&lt;br /&gt;
:- numărul din stânga este deplasat la stânga cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
:- numărul din stânga este deplasat la dreapta cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
&lt;br /&gt;
Funcția executată la un anumit moment este determinată de configurația binară de pe intrarea de comandă (function).&lt;br /&gt;
&lt;br /&gt;
ALU are de asemenea intrare de carry și ieșire de carry, plus alte două ieșiri - indicatori - pentru cazurile când rezultatul este zero și când cei doi operanzi sunt egali.&lt;br /&gt;
&lt;br /&gt;
Intrarea de control va fi facuta pe 4 biti ca sa permita existenta a 16 operatii posibile. Fiecare numar de pe intrarea de control (combinatie de 0 si 1) va reprezenta o operatie din cele de mai sus. Scrierea se va face folosind un bloc &amp;quot;case&amp;quot; in functie de aceasta intrare. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: ALU - descriere structurala===&lt;br /&gt;
 &lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/8f/Subiect_big_alu.pdf subiect_alu.pdf]&lt;br /&gt;
	&lt;br /&gt;
Daca se doreste selectarea doar a anumitor biti dintr-un bus (cum se vrea din instruction) acest lucru se poate face in 2 feluri:&lt;br /&gt;
&lt;br /&gt;
a) cu fir aditional:&lt;br /&gt;
:&amp;#039;&amp;#039;wire [1:0] fir_aditional1;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;assign fir_aditional1 = instruction[11:10];&amp;#039;&amp;#039;&lt;br /&gt;
:// apoi la instantiere: &amp;#039;&amp;#039;.sel(fir_aditional1),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
b) direct in instantiere;&lt;br /&gt;
:la instantierea celor 2 mux4 din stanga, direct: &lt;br /&gt;
::&amp;#039;&amp;#039;.sel(instruction[11:10]),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie mai putin (a nu face toate modulele de calcul separat + instantierea lor) si pentru ca e vorba de operatii simple, se poate pune operatia cu assign direct in top pe un fir declarat acolo, sau si mai prescurtat, direct operatia dorita cand se intantiaza modulul in care aceasta intra. De exemplu, pentru operatia de shift la dreapta care intra in primul multiplexor, se poate pune:  &amp;quot;.in0(data0 &amp;gt;&amp;gt; data1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3:===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/3/3a/Subiect_muxes.pdf subiect_muxes.pdf]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4:===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2e/Subiect_rom_luts.pdf rom_luts.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Sumator cu reprezentare in cifre zecimale===&lt;br /&gt;
Proiectati si verificati un sumator zecimal pentru numere cu 2 cifre&lt;br /&gt;
&lt;br /&gt;
Modulul de top (Figura 1) este alcatuit din 2 blocuri de tip &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;. Fiecare bloc aduna cifrele de pe aceasi pozitie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 1&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
   Top level&lt;br /&gt;
&lt;br /&gt;
[[Fișier: bcdsum.png]]&lt;br /&gt;
&lt;br /&gt;
Blocul &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; (Figura 2) este alctuit din 4 blocuri, 2 sumatoare binare pe 4 biti (de tip &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039;), o instanta de &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039; si un multiplexor elementar mux2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 2&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
   Blocul DIGIT SUM &lt;br /&gt;
&lt;br /&gt;
[[Fișier: digit.png]]&lt;br /&gt;
&lt;br /&gt;
Primul sumator aduna cifrele din domeniul [0...9] avand un rezultat intre [0 ... 18] &lt;br /&gt;
&lt;br /&gt;
Comparatorul are la iesire 1 daca rezultatul este mai mare decat 9.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mic decat 9, acesta este trimis in mod direct la iesirea &amp;#039;&amp;#039;&amp;#039;digit&amp;#039;&amp;#039;&amp;#039; a blocului &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mare decat 9, o crectie este necesara si se aduna 6 la rezultat.&lt;br /&gt;
&lt;br /&gt;
Comparatorul cu valoarea 9 este descris structural din porti in figura de mai jos: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 3&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
   the comparator &lt;br /&gt;
&lt;br /&gt;
[[Fișier: cmp.png]]&lt;br /&gt;
&lt;br /&gt;
Testbench-ul va genera stimuli pentru &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
Intrarea b0 a &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; se schimba la fiecare 5 pasi de simulare .&lt;br /&gt;
&lt;br /&gt;
b1, a0 si a1 se schimba sincron cu b0 ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: teststimuli.png]]&lt;br /&gt;
&lt;br /&gt;
Cerinte:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039;- descris structural la nivel de porti ca in Figura 3.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039; descris comportamental cu un assign continuu.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;mux&amp;#039;&amp;#039;&amp;#039; descris comportamental cu always.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; descris strctural ca in Figura 2.&lt;br /&gt;
# modulul de top numit &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039;, descris structural ca in Figure 1.&lt;br /&gt;
# modulul de testbench, &amp;#039;&amp;#039;&amp;#039;bcdsum_tb&amp;#039;&amp;#039;&amp;#039;, instantiaza &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; cu numele &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# in testbench, generati stimuli pentru intrarile circuitului testat.&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_3_:_Circuite_combinationale_elementare&amp;diff=7886</id>
		<title>CID aplicatii 3 : Circuite combinationale elementare</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_3_:_Circuite_combinationale_elementare&amp;diff=7886"/>
		<updated>2024-10-22T13:54:09Z</updated>

		<summary type="html">&lt;p&gt;Mihai.antonescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Teorie==&lt;br /&gt;
Acest laborator are ca scop scrierea unor circuite combinationale simple si explorarea variantelor de sintaxa diferite ce ajung sa ofere aceeasi functionalitate. Sintaxa va fi explicata in comentariile exemplului rezolvat mai jos.&lt;br /&gt;
&lt;br /&gt;
Descrierea circuitelor in SystemVerilog se face in una din doua forme:&lt;br /&gt;
&lt;br /&gt;
:1) structurala - descrie cum un modul e alcatuit din module sau primitive mai simple&lt;br /&gt;
&lt;br /&gt;
:2) comportamentala/behavioural - descrie cum se calculeaza iesirile din intrari&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exemplu - Decodorul==&lt;br /&gt;
Decodorul este un circuit a carui iesire pe n biti are un singur bit de &amp;quot;1&amp;quot;, anume cel selectat prin singura sa intrare pe log2(n) biti. &lt;br /&gt;
Astfel, pentru un decodor cu iesire pe 8b, intrarea va avea 3b (logaritm in baza 2 din 8) si tabelul de adevar va arata astfel: &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| in(3b) || out(8b) &lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|000 || 0000_0001&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|001 || 0000_0010&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|010 || 0000_0100&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|011 || 0000_1000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|100 || 0001_0000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|101 || 0010_0000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|110 || 0100_0000&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|111 || 1000_0000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Iesirea este numerotata de la bitul 7 (msb) pana la bitul 0 (lsb). Se observa ca daca intrarea are valoare &amp;quot;a&amp;quot;, singurul bit de &amp;quot;1&amp;quot; din iesire este cel de pe pozitia &amp;quot;a&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie:&amp;#039;&amp;#039;&amp;#039; Atat in tabelul de mai sus, cat si in codul SystemVerilog poate sa apara &amp;quot;_&amp;quot; (underscore) ca sa ajute vizual la separarea/numararea cifrelor. Se foloseste in mod uzual la scrierea in binar ca sa grupeze 4b (o cifra in hexa).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Circuitul exemplu al acestui laborator va fi un decodor mai mic, cu 2 biti de intrare si 4 de iesire, avand tabelul de adevar:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|- bgcolor=&amp;quot;#ddeeff&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| in(2b) || out(4b) &lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|00 || 0001&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|01 || 0010&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|10 || 0100&lt;br /&gt;
|- bgcolor=&amp;quot;#ddffdd&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
|11 || 1000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
O varianta de schema care implementeaza acest circuit este cea de mai jos: &lt;br /&gt;
&lt;br /&gt;
[[Fișier:w3_exemplu_rezolvat.png ‎| 600px]]&lt;br /&gt;
&lt;br /&gt;
In circuitul de mai sus, apare dubla negatie, respectivul semnal putand fi luat si direct de la intrare. Acest lucru se intampla din considerente electrice. Desi pe desene nu sunt trecute, fiecare poarta are si fire de alimentare si de masa. Astfel, pentru a evita fire de lungimi foarte mari sau fire care se propaga in multe intrari si probleme de cadere a tensiunilor, se folosesc astfel de buffere/repetoare. &lt;br /&gt;
&lt;br /&gt;
Codul de mai jos exemplifica moduri diferite de a exprima aceasta functionalitate.&lt;br /&gt;
El contine comentarii referitoare la sintaxa de baza SystemVerilog, necesara implementarii modulelor in diverse moduri. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor - varianta structurala din porti, cu primitive (fisierul decodor_v1.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v1&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,	// definirea intrarilor sub forma de &amp;quot;bus&amp;quot; &lt;br /&gt;
									// bus-ul de intrare se numeste &amp;quot;in&amp;quot; si este pe 2 biti: in[1], in[0]&lt;br /&gt;
									// fizic sunt 2 fire distincte, grupate pentru o mai simpla folosire.&lt;br /&gt;
		output logic [3:0] out 	// avem o iesire, numita &amp;quot;out&amp;quot; pe 4 biti.&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
logic in_0_inv;&lt;br /&gt;
logic in_1_inv;&lt;br /&gt;
logic in_0_nat;&lt;br /&gt;
logic in_1_nat;&lt;br /&gt;
&lt;br /&gt;
not not_gate_0(in_0_inv,in[0]); // aleg bitul 0 al lui in sa intre in aceasta poarta not;&lt;br /&gt;
&lt;br /&gt;
not not_gate_1(in_1_inv,in[1]); // observatie: cele 2 fire si cele 2 porti putea fi comprimate intr-un bus + poarta not pe 2 biti.&lt;br /&gt;
&lt;br /&gt;
not not_gate_2(in_0_nat,in_0_inv);&lt;br /&gt;
&lt;br /&gt;
not not_gate_3(in_1_nat,in_1_inv);&lt;br /&gt;
&lt;br /&gt;
and and_gate_0(out[0],in_1_inv,in_0_inv);&lt;br /&gt;
&lt;br /&gt;
and and_gate_1(out[1],in_1_inv,in_0_nat);&lt;br /&gt;
&lt;br /&gt;
and and_gate_2(out[2],in_1_nat,in_0_inv);&lt;br /&gt;
&lt;br /&gt;
and and_gate_3(out[3],in_1_nat,in_0_nat);&lt;br /&gt;
	&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor - varianta cu assign, urmand schema (fisierul decodor_v2.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v2&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
	// fiecare bit din iesire calculat independent&lt;br /&gt;
assign out[0] = ~in[0] &amp;amp; ~in[1];&lt;br /&gt;
assign out[1] = in[0] &amp;amp; ~in[1];&lt;br /&gt;
assign out[2] = ~in[0] &amp;amp; in[1];&lt;br /&gt;
assign out[3] = in[0] &amp;amp; in[1];&lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu assign, cu operatorul &amp;quot;?&amp;quot; (fisierul decodor_v3.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v3&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
// operatorul &amp;quot;?&amp;quot;: identic c/c++; (conditie) ? (if_true) : (if_flase);&lt;br /&gt;
&lt;br /&gt;
assign out = (in==0) ? // if in == 0 &lt;br /&gt;
				1 : // if true: out = 1 &lt;br /&gt;
				(in==1) ? // else, verifica alt if. &lt;br /&gt;
					2 : // if in !=0 si in == 1&lt;br /&gt;
					(in==2) ?&lt;br /&gt;
						4 :&lt;br /&gt;
						8; // last case in==3&lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu always cu if (fisierul decodor_v4.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v4&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out&lt;br /&gt;
	);						 &lt;br /&gt;
&lt;br /&gt;
always_comb // mereu cand se schimba orice semnal, se &amp;quot;executa&amp;quot; ce e mai jos; &lt;br /&gt;
            // always_comb genereaza un circuit combinational&lt;br /&gt;
begin	// begin si end pe post de acolade din c/c++; delimiteaza if/else si altele asemenea; inclusiv always cu totul&lt;br /&gt;
	if(in == 0)&lt;br /&gt;
		begin // nota autorului: eu prefer sa pun begin/end asa. ele se pot pune si dupa conditie sau aliniate altfel.&lt;br /&gt;
				// ^ preferinta personala legata de coding style, important e sa fiti consecventi in cum scrieti&lt;br /&gt;
		out = 1; &lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		begin&lt;br /&gt;
		if(in == 1)&lt;br /&gt;
			out = 2;	// fiind o singura instructiune, begin/end se poate omite (identic c/c++)&lt;br /&gt;
		else&lt;br /&gt;
			begin	// nota autorului: eu personal le pun mereu. in caz ca mai adaug linii in if dupa, sa fie deja puse&lt;br /&gt;
			if(in == 2)&lt;br /&gt;
				begin&lt;br /&gt;
				out = 4;&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				begin&lt;br /&gt;
				out = 8;&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
end//end pt always&lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu always cu case (fisierul decodor_v5.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v5&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
always_comb&lt;br /&gt;
begin&lt;br /&gt;
	case(in) // functioneaza ca switch/case din c/c++; sintaxa usor diferita&lt;br /&gt;
		0: // if in == 0&lt;br /&gt;
			begin&lt;br /&gt;
			out = 1;&lt;br /&gt;
			end&lt;br /&gt;
		2&amp;#039;d1: // if in == 1;	2&amp;#039;d1 se traduce: pe 2 biti, in baza zece (eng: decimal, &amp;quot;d&amp;quot;), valoarea 1&lt;br /&gt;
			begin	// pt &amp;quot;0&amp;quot; de mai sus: daca nu se pune nimic se considera in baza zece.&lt;br /&gt;
			out = 2;&lt;br /&gt;
			end&lt;br /&gt;
		2&amp;#039;b10: // if in == 2;	scris in binar &amp;quot;b&amp;quot;, 2&amp;#039;b10 =&amp;gt; adica valoarea 2(10 binar) pe 2 biti &lt;br /&gt;
			begin&lt;br /&gt;
			out = 4;&lt;br /&gt;
			end&lt;br /&gt;
		2&amp;#039;h3: // if in == 3;	scris in hexa (baza 16 &amp;quot;h&amp;quot;, se poate si &amp;quot;x&amp;quot;), fiind numar mic, nu se vede diferenta fata de zecimal.&lt;br /&gt;
			begin&lt;br /&gt;
			out = 8;&lt;br /&gt;
			end&lt;br /&gt;
		default: // daca in == un caz netrat; &lt;br /&gt;
			begin // aici inutil pt ca am tratat toate cazurile posibile; pus ca exemplu de sintaxa &lt;br /&gt;
			out = 0;&lt;br /&gt;
			end&lt;br /&gt;
	endcase // orice &amp;quot;case&amp;quot; se inchide cu &amp;quot;endcase&amp;quot;&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;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului decodor -  varianta cu assign comportamental  (fisierul decodor_v6.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module decodor_v6&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out &lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign out = 1 &amp;lt;&amp;lt; in; &lt;br /&gt;
	// prin shiftare&lt;br /&gt;
	// 1&amp;lt;&amp;lt;0 == 1 == 4&amp;#039;b0001; &lt;br /&gt;
	// 1&amp;lt;&amp;lt;1 == 2 == 4&amp;#039;b0010; &lt;br /&gt;
	// 1&amp;lt;&amp;lt;2 == 4 == 4&amp;#039;b0100; &lt;br /&gt;
	// 1&amp;lt;&amp;lt;3 == 8 == 4&amp;#039;b1000; &lt;br /&gt;
&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Descrierea modulului top  (fisierul top.sv):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
// observatie: &lt;br /&gt;
	// puteti da in vivado: rtl analysis -&amp;gt; open elaborated design -&amp;gt; schematic pentru a vedea desenul rezultat&lt;br /&gt;
	// puteti vedea ca moduri diferite de scriere produc aparitia a diferite primitive de sinteza&lt;br /&gt;
module top&lt;br /&gt;
	(&lt;br /&gt;
		input logic [1:0] in,&lt;br /&gt;
		output logic [3:0] out_v1, // fiecare varianta de decodor cu iesirea lui&lt;br /&gt;
		output logic [3:0] out_v2, // toate ar trebui sa scoata acelasi rezultat &lt;br /&gt;
		output logic [3:0] out_v3,&lt;br /&gt;
		output logic [3:0] out_v4,&lt;br /&gt;
		output logic [3:0] out_v5,&lt;br /&gt;
		output logic [3:0] out_v6&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v1 decodor_v1_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
decodor_v2 decodor_v2_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v2)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v3 decodor_v3_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v3)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v4 decodor_v4_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v4)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
decodor_v5 decodor_v5_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v5)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
decodor_v6 decodor_v6_0&lt;br /&gt;
	(&lt;br /&gt;
		.in(in),&lt;br /&gt;
		.out(out_v6)&lt;br /&gt;
	);&lt;br /&gt;
	&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
===Exercitiul 1: Multiplexorul===&lt;br /&gt;
&lt;br /&gt;
Multiplexorul (mux) este un circuit ce are rolul de a selecta una dintre intrari pentru ca aceasta sa ajunga la iesire.&lt;br /&gt;
&lt;br /&gt;
Imaginati-va o intersectie in care toate masinile vor sa se iasa catre aceasi strada. Pentru a evita accidente, este nevoie de un element de control, de selectie, prin care se hotaraste care dintre intrari este lasata sa ajunga la iesire, in respectivul moment de timp.&lt;br /&gt;
Multiplexorul poate fi de asemenea vazut ca un comutator.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 1:&amp;#039;&amp;#039;&amp;#039; conceptul de baza al multiplexarii este absolut vital si o sa apara des in multe zone ale ingineriei si la materii foarte diferite. &lt;br /&gt;
Ca niste mici exemple, el se foloseste in:&lt;br /&gt;
:a) telecomunicatii - cine are voie sa comunice pe un fir la un moment de timp &lt;br /&gt;
:b) internet - routere - cine trimite pachetele tcp/ip catre destinatia x&lt;br /&gt;
:c) panouri cu leduri - aprindere pe rand a ledurilor (de la instalatii de craciun pana la ecrane/televizoare care aprind randurile alternativ)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 2:&amp;#039;&amp;#039;&amp;#039; numarul de intrari maxim posibile este 2^(nr_biti_selectie)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 3:&amp;#039;&amp;#039;&amp;#039; multiplexoarele pot avea intrarile date si iesirea pe mai multi biti.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 4:&amp;#039;&amp;#039;&amp;#039; este de ajutor sa incepeti sa vedeti circuitele ca avand o cale de date ce sunt procesate si o cale de control care decide cum se face asta.&lt;br /&gt;
Aici calea de date este alcatuita din intrari si iesire, iar calea de control din firele de selectie. &lt;br /&gt;
Acest principiu se propaga si in arhitectura microprocesoarelor unde vor aparea magistrale si memorii de date/instructiuni.&lt;br /&gt;
&lt;br /&gt;
Pornind de la exemplul oferit, implementati multiplexorul in cat mai multe variante.&lt;br /&gt;
&lt;br /&gt;
Multiplexorul cu 2 intrari pe un bit fiecare (mux elementar) este desenat in figurile de mai jos: cum este vazut din exterior (prima figura) si alcatuirea lui interna (a doua figura). &lt;br /&gt;
&lt;br /&gt;
[[Fișier:mux2_general.png ‎| 300px]]&lt;br /&gt;
[[Fișier:mux2_schema_interna.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 10ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_mux2.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: Implementati un mux4 (multiplexor cu 4 intrari)===&lt;br /&gt;
&lt;br /&gt;
Interfata lui este ca in figura de mai jos. &lt;br /&gt;
&lt;br /&gt;
[[Fișier:mux_general.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Pentru varianta lui structurala, mux4 se construieste din mai multe mux2 legate corespunzator. Incercati sa construiti voi aceasta schema.&lt;br /&gt;
&lt;br /&gt;
Pentru testarea circuitului, generati in testbench urmatoarele forme de unda (liniile punctate reprezinta 10ns): &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Wavedrom_mux4.png ‎| 500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Demultiplexorul===&lt;br /&gt;
&lt;br /&gt;
Demultiplexorul (demux) este un circuit ce are rolul de a selecta catre care iesire se va duce intrarea. &lt;br /&gt;
Imaginati-va o intersectie in care intra o singura masina si trebuie sa decida daca iese catre stanga/inainte/dreapta. 	&lt;br /&gt;
&lt;br /&gt;
Pentru acest exercitiu se va implementa un demux2 (cu 2 iesiri).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 1&amp;#039;&amp;#039;&amp;#039;: celelalte iesiri, cele neselectate iau valoarea 0.&lt;br /&gt;
	&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observatie 2&amp;#039;&amp;#039;&amp;#039;: numarul de iesiri maxim posibile este 2^(nr_biti_selectie)&lt;br /&gt;
&lt;br /&gt;
Interfata demultiplexorului este data mai jos. Incercati sa construiti acest circuit in cat mai multe variante de sintaxa posibile (minim4).	&lt;br /&gt;
&lt;br /&gt;
[[Fișier:demux2_general.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Generati forme de unda pentru a vedea functionarea demultiplexorului.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Sumatorul===&lt;br /&gt;
&lt;br /&gt;
Sumatorul are rolul de a scoate la iesire suma celor 2 intrari.&lt;br /&gt;
&lt;br /&gt;
Uzual el mai are si intrare si iesire de &amp;quot;carry&amp;quot; adica de transport (cand se depaseste baza de numarare si e nevoie de inca o cifra, ex in zecimal: 88 + 20 = 108; apare o cifra in plus, cifra sutelor). &lt;br /&gt;
&lt;br /&gt;
[[Fișier:sumator_8b_general.png ‎| 300px]]&lt;br /&gt;
&lt;br /&gt;
Observatie: desi scrierea cu assign si + este cea mai usoara si clara pentru un sumator, si celelalte moduri de scriere sunt posibile.&lt;br /&gt;
La aceasta scriere, daca se doresta ca sumatorul sa aiba carry out, sumatorul se poate face cu un bit mai mare decat intrarile, iar acel bit sa fie conectat la carry out. Practic, obtii un rezultat pe &amp;quot;n&amp;quot; biti + un bit de depasire, anume msb-ul. &lt;br /&gt;
&lt;br /&gt;
Generati formele de unda necesare testarii sumatorului pe 8b.&lt;br /&gt;
&lt;br /&gt;
Pentru a vedea pas cu pas cum se construieste un sumator pe 8b puteti parcurge urmatoarea platforma de laborator: [https://wiki.dcae.pub.ro/images/0/0f/Cid_gan_sumator_aplicatia_2.pdf Sumator.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Comparatorul===&lt;br /&gt;
&lt;br /&gt;
Comparatorul are rolul de a vedea relatia dintre cele 2 intrari ale sale, daca cele 2 numere sunt egale, daca primul e mai mic sau mai mare. &lt;br /&gt;
&lt;br /&gt;
Astfel el poate avea 3 iesiri dintre care se activeaza doar una: &lt;br /&gt;
:- iesire de egalitate&lt;br /&gt;
:- iesire de in0 &amp;lt; in1 &lt;br /&gt;
:- iesire de in0 &amp;gt; in1 &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
Se mai poate face si o varianta de comparator cu 2 iesiri, asa cum veti studia la arhitectura microprocesoarelor.&lt;br /&gt;
:- iesire de egalitate&lt;br /&gt;
:- iesire care este 0 daca in0&amp;lt;in1 sau 1 daca in0&amp;gt;in1&lt;br /&gt;
&lt;br /&gt;
Aceasta abordare este folosita la AMP la flag-urile din procesoare, folosind operatia de scadere si flag-urile de &amp;quot;zero&amp;quot; si &amp;quot;negativ&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Scrieti modulul de comparator, in ambele variante de interfata. Intrarile pot avea oricat de multi biti (comparator mai mic sau mai mare), pentru acest exercitiu sa il faceti pe 4b.&lt;br /&gt;
&lt;br /&gt;
Scrieti un testbench care sa genereze toate combinatiile posibile de date de la intrare. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Discutie&amp;#039;&amp;#039;&amp;#039;: Daca acest comparator are datele pe 32b sau mai mult (sau daca circuitul devine mult mai complex), nu se mai poate face o astfel de testare exhaustiva a combinatiilor posibile de date de la intrare pentru ca simularea ar dura prea mult. De situatia asta se ocupa inginerii de verificare ce lucreaza in paralel cu inginerii de design. Pentru mai multe detalii puteti cauta &amp;quot;constrained random functional verification&amp;quot;. Incercati sa identificati cazurile/situatiile ce ar trebui testate pentru un comparator pe 32b inainte de a spune ca acesta functioneaza corect (minim 10).&lt;/div&gt;</summary>
		<author><name>Mihai.antonescu</name></author>
	</entry>
</feed>