Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml


Introducere in ModelSIM

algoritmi



+ Font mai mare | - Font mai mic



Lucrarea 1. Introducere in ModelSIM

  1. Scopul lucrarii

In aceasta lucrare se realizeaza familiarizarea cu programul de simulare ModelSIM, cu sintaxa VHDL si se vor testa circuite simple.

  1. Desfasurarea lucrarii


Deschiderea unui proiect in ModelSIM

Odata deschis programul de simulare, se schimba calea in directorul curent de lucru: C:ModelTechwork, folosind FileChange Directory si selectand calea respectiva.

In directorul curent, se pot vedea mai multe librarii: atat librariile dedicate, deja existente, cat si entitatile (circuitele) create de catre utilizator. Se va selecta libraria WORK, in care se vor elabora circuitele.

In aceasta librarie, se deschide un proiect: FileNewProject, iar in proiect se deschide un fisier nou.

Fisierul .vhd are urmatoarea structura, in care sunt inserate explicatii:

library IEEE;

--se incarca libraria IEEE si tipurile de date si

--cuvintele cheie aferente

use IEEE.std_logic_1164.all;

use IEEE.std_logic_arith.all;

use IEEE.std_logic_unsigned.all;

--se foloseste pachetul std_logic din libraria ieee

--declararea entitatii

entity <nume_entitate> is

--parametru configurabil tipic unei entitati

--de exemplu, o entitate poate fi instantiata

--in cadrul unei aplicatii de mai multe ori

--cu alti parametri (de ex. numarul de biti pe care sunt reprezentate

--esantioanele)

generic (

<parametru> : <tip> );

--enumerarea porturilor

port(

<port_intrare> : in <tip>; --port de intrare

----- ----- --------- ----- ------

<port_iesire> : out <tip> --port iesire

);

end <nume_entitate>;   

architecture <nume_arhitectura> of <nume_entitate> is

--declararea semnalelor

signal <nume_semnale> : <tip>;

--declararea componentelor

component <nume_componenta> is

generic (

<parametru> : <tip> );

--enumerarea porturilor

port(

<semnal_intrare> : in <tip>;

----- ----- --------- ----- ------

<semnal_iesire> : out <tip>

);

end component;   

begin

<continut_arhitectura>

end ;

Declararea entitatii incepe cu declararea porturilor. Porturile pot fi de intrare (in), iesire (out) sau de intrare/iesire (inout). Tipul portului trebuie precizat explicit.

Separarea tipurilor de porturi se face prin ';', mai putin inaintea unei paranteze inchise ')'.

Tipurile de date tipice folosite sunt:

natural (pentru parametri)

std_logic (pentru semnale), ce pot lua valorile bitilor : '0', '1', 'X', 'U' (Undefined) sau 'Z' (high Z)

std_logic_vector, pentru vectori de biti (cazul unor esantioane ce sunt reprezentate ca siruri de biti)

Numele arhitecturii nu este important. In cadrul acestei arhitecturi, se declara semnalele din interiorul entitatii, care nu au interfata cu exteriorul sau alte entitati deja formate (si compilate) ce se folosesc in interiorul entitatii curente. Aceste entitati poarta in acest context denumirea de componente.

Continutul arhitecturii este format din declararea de procese (curente) si din instantierea componentelor declarate.

Un proces are urmatoarea structura:

process(<lista_senzitivitati>)

variable <nume_variabila> : <tip>;

begin

<continut_proces>

end process;

Lista de senzitivitati contine numele de semnale (interne sau pe porturile de intrare) care genereaza pornirea procesului in momentul in care unul din aceste semnale se schimba.

Instantierea unei componente presupune doua lucruri:

denumirea componentei instantiate (o componenta declarata poate fi instantiata de mai multe ori in cadrul unei entitati, deci fiecare bloc instantiat trebuie sa poarte un nume distinct)

maparea (realizarea corespondentei) intre porturile componentei si semnalele din interiorul entitatii.

<nume_bloc> : <nume_componenta>

generic map(<numele parametrilor mapati>)

port map(<numele semnalelor mapate>)

In lucrarile urmatoare se va exemplifica pe larg folosirea notiunilor de mai sus.

Scrierea unui program simplu

Sa exemplificam notiunile de mai sus cu un circuit simplu: bistabilul de tip D. Schema bloc a acestuia este prezentata in Fig. 1.1.

Fig. 1. . Schema bloc a bistabilului de tip D

Un astfel de circuit memoreaza valoarea primita pe portul iDATA pe frontul crescator al ceasului iCLK, timp de o perioada de ceas, furnizand-o pe iesirea oDATA la urmatorul front crescator de ceas. Semnalul de iRESET reseteaza neconditionat iesirea atunci cand este activ (nivel logic '1'). Cum resetarea iesirii nu se face pe ceas, vom spune ca semnalul de reset este asincron.

Observatii

Fara a fi o conditie obligatorie, recomandam ca numele porturilor sa inceapa cu caracterul 'i' daca acestea sunt porturi de intrare sau cu 'o' daca sunt de iesire.

Codul VHDL nu este "case sensitive".

Procesul corespunzator va avea in lista de senzitivitati:

iRESET (de valoarea lui depinde direct iesirea si orice modificare a acestuia trebuie sesizata)

iCLK (iesirea, daca nu este resetata, se modifica in momentul in care se detecteaza un front crescator de ceas)

Se va deschide un fisier nou: "bistabil.vhd".

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_arith.all;

use IEEE.std_logic_unsigned.all;

entity bistabil is

port(

iRESET : in std_logic;

iCLK : in std_logic;

iDATA : in std_logic;

----- ----- --------- ----- ------

oDATA : out std_logic

);

end bistabil;   

architecture behave of bistabil is

begin

process(iRESET,iCLK)

begin

if iRESET='1' then

oDATA <= '0';

elsif rising_edge(iCLK) then

oDATA <= iDATA;

end if;

end process;

end ;

Observatii

la atribuirea valorii unui semnal, se foloseste '<='

la testarea valorii unui semnal, se foloseste '=' (cazul testarii lui iRESET)

testarea frontului crescator al ceasului se face cu functia rising_edge(<nume semnal>)

valoarea fixa atribuita unei variabile std_logic se face intre apostrofuri: ex.: '1', '0'

valoarea fixa atribuita unei variabile std_logic_vector se face intre ghilimele: ex.: "000", "1101".

In corpul procesului s-a folosit o instructiune de testare

if <conditie>

end if;

S-a simplificat:

if <conditie>

then <>;

else if <conditie 2>

then <>;

else <>;

end if;

end if;

cu

if <conditie>

then <>;

elsif <conditie 2>

then <>;

else <>;

end if;

Testarea circuitului

Odata scris codul entitatii, aceasta trebuie compilata si apoi simulata.

Compilarea unei anumite entitati se face folosind butonul special de Compile din linia de comanda. Se corecteaza eventualele erori de sintaxa si se recompileaza fisierul. Se poate compila numai fisierul selectat sau se pot compila toate fisierele din proiect.

Dupa compilare, entitatea poate fi simulata, folosind butonul corespunzator.

De fiecare data, in linia de comanda vor fi afisate instructiunile corespunzatoare ModelSIM (fara legatura cu codul VHDL). Practic, daca se prefera, in locul butoanelor de shortcut din meniu se pot tasta direct in linia de comanda aceste instructiuni (vsim, vcom) cu parametrii respectivi.

vcom <nume_fisier>

In vederea simularii si a testarii bunei functionari, semnalelor de pe porturile de intrare le trebuie atribuite anumite valori in timp. Exista doua posibilitati de atribuire:

se forteaza anumite valori pentru semnale de la inceputul simularii si se ruleaza simularea un anumit timp (cat se doreste) tsim. Daca pe parcurs se doreste modificarea vreunuia dintre semnale, se ruleaza simularea mai intai cu valorile initiale pe durata tsim1, se forteaza noile valori si se mai ruleaza tsim2, astfel incat tsim=tsim1+tsim2.

Din linia de comanda, pentru fiecare semnal in parte se introduce cate o instructiune care descrie comportarea in timp a fiecarei intrari.

force -freeze sim:/<nume_entitate>/<nume_port_in> <valoare_initiala> <offset [ns]>, <valoare_modificata>

In cazul nostru, sa imaginam un semnal iDATA egal cu 1, care se reseteaza dupa 12ns. Ceasul sistemului va fi 10ns, iar iRESET este '1' si se reseteaza dupa 5ns.

force -freeze sim:/bistabil/ireset 1 0, 0

force -freeze sim:/bistabil/iclk 1 0, 0 -r 10ns

force -freeze sim:/bistabil/idata 1 0, 0

Observatii

Din linia de comanda, folosind optiunea [-r], se poate periodiciza un semnal, asa cum s-a procedat cu semnalul de ceas, periodic cu 10ns.

Implicit duratele sunt exprimate in [ns], daca nu se precizeaza altfel.

Pentru a vizualiza toate semnalele din entitate pe fereastra de forma de unda (wave), este necesara introducerea instructiunii

add wave sim:/bistabil/*

Rularea se face pentru 30ns.

run 30 ns

Observati formele de unda si anume:

cum actioneaza iRESET

cum se modifica iesirea in functie de intrare si de ceas

Modificati semnalul de reset astfel incat circuitul sa fie resetat din nou dupa alte 24ns. Pentru aceasta, inainte de modificarea propriu-zisa a semnalului, simularea trebuie repornita:

restart

Exercitii

Proiectati un circuit secvential care realizeaza o detectie de front crescator a unui semnal de intrare asincron, iDATA. Daca se detecteaza o tranzitie de-a lungul unei perioade de ceas, se seteaza un semnal de iesire oFLAG pe o perioada de ceas. Se pot detecta mai multe tranzitii pe o perioada de ceas?

Similar 1 pentru front descrescator.

Proiectati un latch SR (Set/Reset). Acesta seteaza sau reseteaza iesirea dupa cum la intrare are S='1' sau R='1'. Valorile S, R sunt luate in considerare numai pe palierul de '1' al ceasului. Comutarea din '1' in '0' nu este detrminata de resetarea lui S, ci numai de valoarea de '1' a lui R. Similar pentru comutarea inversa. R este prioritar (daca ambele intrari au valoarea '1').

Proiectarea unui numarator pe N biti

Intrarile si iesirile numaratorului sunt reprezentate in figura.

Fig. 1. . Structura numaratorului

Counterul numara pe N biti, iar semnalele de intrare au urmatoarele semnificatii:

iCOUNT

pe '1' numaratorul incrementeaza sau decrementeaza valoarea anterioara, dupa cum iUD este '1', respectiv '0'

Cand iLD, numaratorul este incarcat cu valoarea iVAL. Daca si iCOUNT, si iLD sunt setate, prioritar este iCOUNT si counterul numara.

Fisierul "numarator.vhd" este descris mai jos:

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_arith.all;

use IEEE.std_logic_unsigned.all;

entity numarator is

--parametrul N, implicit ales 4

generic(

N : natural :=4);

port(

iRESET : in std_logic;

iCLK : in std_logic;

iCOUNT : in std_logic;

iUD : in std_logic;

iLD : in std_logic;

iVAL : in std_logic_vector(N-1 downto 0);

----- ----- --------- ----- ------

oVAL : out std_logic_vector(N-1 downto 0)

);

end numarator;   

architecture behave of numarator is

--registrul acumulator al numaratorului

signal sVAL : std_logic_vector(N-1 downto 0);

begin

process(iRESET,iCLK)

begin

if iRESET='1' then

sVAL <= (others => '0');

elsif rising_edge(iCLK) then

if iCOUNT='1' then --numara

if iUD='1' then

sVAL <= sVAL + '1';--incrementeaza

else sVAL <= sVAL - '1';--decrementeaza

end if;

elsif iLD='1' then -incarca valoarea iVAL

sVAL <= iVAL;

end if;

end if;

end process;

oVAL <= sVAL;

end ;

Observatii

Adunarea se reprezinta in ModelSIM ca atare. Daca operanzii nu au acelasi numar de biti, ModelSIM prelungeste cu zerouri in partea cea mai semnificativa operandul cu mai putini biti.

Sintaxa (others => '0') atribuie tuturor bitilor unui vector valoarea inscrisa (in cazul acesta '0'). Este utila in momentul in care numarul de biti ai numaratorului este un parametru.

Exercitii

  1. Simulati numaratorul de mai sus cu urmatoarele ipoteze;

N=4;

iVAL are valoarea "0010"

iLD este resetat pana la momentul t1=67ns si apoi setat.

iCOUNT este setat pana la momentul t2=80ns si apoi resetat.

iUD este '1' pana la momentul t3=34ns si apoi resetat.

Realizati teoretic o diagrama temporala si apoi verificati corectitudinea codului.

  1. Introduceti o intrare suplimentara care sa reprezinte incrementul/decrementul acumulatorului (nu neaparat '1').
  2. Proiectati un numarator care sa numere numai inainte (UP), dar care sa se dea peste cap (wrap) in momenul in care atinge valoarea iLIM, pe care o primeste pe un port de intrare. De exemplu, daca numarul de biti este 4, iar iLIM este "0101", iesirea numaratorului va fi: "0000", "0001", "0010", "0011", "0100", "0101", "0000", ..
  3. Folosind o parte din procesul numaratorului, proiectati un circuit care sa realizeze un ceas avand perioada NּTCK (divizor de ceas). Factorul de umplere este 50% (ca pentru un ceas normal).
  4. Proiectati un circuit care sa realizeze un semnal avand perioada NּTCK si palierul de '1' de durata TCK (factor de umplere 1/N).
  5. Proiectati un registru paralel-serie. Datele vin la o rata de 40ns in esantioane pe 4 biti si trebuie serializate la o rata de 10ns, incepand cu LSB.
  6. Similar 6 pentru un registru serie-paralel.


Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 1465
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved