CID aplicatii 4 : Memorii ROM

De la WikiLabs
Versiunea din 21 februarie 2022 12:34, autor: Gvpopescu (discuție | contribuții) (Pagină nouă: == Memoria ROM== Memoria este un dispozitiv electronic utilizat pentru stocarea datelor. Aceasta poate fi de mai multe feluri, având diverse caracteristici, cum ar fi capacitatea...)
(dif) ← Versiunea anterioară | Versiunea curentă (dif) | Versiunea următoare → (dif)
Jump to navigationJump to search

Memoria ROM

Memoria este un dispozitiv electronic utilizat pentru stocarea datelor. Aceasta poate fi de mai multe feluri, având diverse caracteristici, cum ar fi capacitatea de a-și păstra sau nu conținutul după întreruperea alimentării sau capacitatea de a-și modifica sau nu conținutul după terminarea procesului de producție.

Memoria ROM (Read-Only Memory) este un circuit combinational folosit pentru stocarea unor date ce pot fi accesate cu ajutorul unei intrari de adresă. Asa cum sugerează și numele, memoria ROM clasică nu poate fi modificată. În plus, datorită modului în care este implementată, ea își păstrează conținutul după întreruperea alimentării (este nevolatilă).

Pentru a înțelege termenul de memorie, putem face următorul exercițiu de imaginație: să ne gândim la un dulap cu mai multe sertare. Conținutul memoriei este reprezentat de conținutul sertarelor, iar adresele sunt reprezentate de etichetele lipite pe aceste sertare pentru a le identifica. Dacă avem nevoie de conținutul unui sertar, va trebui să știm eticheta aferentă acestuia (adresa).

O memorie ROM are următorii parametri: numărul de biți ai adresei, care este legat de numarul de locații de memorie (cu n biți de adresă putem forma 2𝑛 combinații diferite, deci putem accesa maxim 2𝑛 locații de memorie) și dimensiunea locației de memorie, care ne spune cât de multă informație poate stoca o locație de memorie.


Să urmărim exemplul din figura următoare:

ROM memory.PNG


Aici, adresa are dimensiunea de 4 biți, asadar putem accesa cu aceasta 16 locații diferite de memorie. Dimensiunea fiecărei locații este de 8 biți, așadar fiecare locație de memorie poate stoca numere de 8 biți. Spunem că memoria ROM este o memorie 16x8. Capacitatea acestei memorii este de 16 x 8 biți = 128 biți.

Exemple

Exemplul 1: Decodorul

Decodorul este circuitul care, pentru o anumită valoare a intrării, va genera la ieșire un șir binar care conține 1 pe poziția cu indicele egal cu valorea intrării și 0 in rest. De exemplu, decodorul de mai jos pe 2 biți va avea următoarea corespondență intrare-iesire:

in out
2'b00 4'b0001
2'b01 4'b0010
2'b10 4'b0100
2'b11 4'b1000

Decoder.PNG

Vom implementa acest circuit ca memorie ROM.

Implementarea Verilog a circuitului

module Decoder(
  input [1:0] in,
  output reg [3:0] out
  );

  always@(in) begin
    case(in)
      2'b00: out = 4'b0001;
      2'b01: out = 4'b0010;
      2'b10: out = 4'b0100;
      2'b11: out = 4'b1000;
      default: out = 4'b0000;
    endcase
  end

endmodule


Implementarea Verilog a modulului de test

`timescale 1ns/1ps

module Decoder_TB();
  reg [1:0] in_tb;
  wire [3:0] out_tb;
  
  integer idx;

  initial begin
    for(idx=0; idx<4; idx = idx + 1) begin
      in_t = idx;
      #1;
    end 
    #2 $stop();
  end

  Decoder DUT(
    .in(in_tb),
    .out(out_tb)
  );

endmodule

Observații:

  • Circuitul Decoder va avea o intrare pe 2 biți, care va reprezenta adresa memoriei ROM și o iesire pe 4 biți, reprezentând conținuturile memoriei ROM corespunzătoare fiecărei combinații de la intrare.
  • Chiar dacă în interiorul instrucțiunii case se acoperă toate cazurile posibile (toate combinațiile de 2 biți), este bine sa punem și un default pentru a evita inserarea în locul circuitului combinațional dorit (aici, memoria ROM) a unui latch.


Exemplul 2: Transcodorul

Trancodorul este o memorie ROM care asociază unei anumite intrări, reprezentată de adresă, un anumit cod, reprezentat de conținutului locației de memorie asociată acelei adrese.

In acest exemplu, vom folosi transcodorul pentru a realiza un modul ce controlează afișajul cu 7 segmente. Acest dispozitiv de afișare este format, așa cum sugerează și numele, din 7 segmente ce pot fi controlate separat. Putem aprinde sau stinge fiecare segment controlând tensiunea aplicată pe acesta. Pentru acest afișaj, comanda este negativă: aplicând 0 logic pe un segment acesta se va aprinde, iar aplicând 1 logic, acesta se va stinge.

Structura unui afisaj cu 7 segmente este prezentată în imaginea de mai jos:

7LED display.PNG

Pentru a realiza controlul afișării, avem nevoie de o memorie ROM ce trebuie să asocieze codului binar al fiecărui element ce poate fi afișat un șir de biți care sting sau aprind diversele segmente ale afișajului, astfel încât să apară imaginea elementului dorit.

Pentru a reprezenta, de exemplu, cele 16 numere hexa, segmentele trebuie aprinse conform Anexei 1. De exemplu, pentru primele 8 numere (0 până la 7), tabelul de asociere este următorul:

Număr Cod intrare Șir de afisare
0 4'b0000 7'b100_0000
1 4'b0001 7'b111_1001
2 4'b0010 7'b010_0100
3 4'b0011 7'b011_0000
4 4'b0100 7'b001_1001
5 4'b0101 7'b001_0010
6 4'b0110 7'b000_0010
7 4'b0111 7'b111_1000

Implementarea Verilog a modulului Display7Seg

module Display7Seg(
  input [3:0] in,
  output reg [6:0] out
  );

  always@(in) begin
    case(in)
      4'd0: out = 7'b1000000;
      4'd1: out = 7'b1111001;
      4'd2: out = 7'b0100100;
      4'd3: out = 7'b0110000;
      4'd4: out = 7'b0011001;
      4'd5: out = 7'b0010010;
      4'd6: out = 7'b0000010;
      4'd7: out = 7'b1111000;
      default: out = 7'b0000110;
    endcase 
  end

endmodule

Exerciții:

Exercițiul 1

Completați codul din Exemplul 2 astfel încât să se poată reprezenta toate numerele în bază hexa, conform Anexei 1

Exercițiul 2

Un procesor are nevoie de un șir de biți numit instrucțiune pentru a știi ce trebuie să facă. Această instrucțiune codează în șirul său de biți toate informațiile necesare.

De exemplu, pentru un grup de instrucțiuni care operează cu registre, aceste informații pot fi:

  • codul instrucțiunii (operation code - opcode): un șir de biți care ne spune ce operație se execută.
  • destinația: un șir de biți care codează numărul registrului destinație.
  • sursa1: un șir de biți care codează numărul registrului folosit ca operand 1.
  • sursa2: un șir de biți care codează numărul registrului folosit ca operand 2.


Vom considera codul operației pe 4 biți, ceea ce inseamnă ca putem avea 16 instrucțiuni diferite. ]n plus, câmpurile care codează destinația și cei doi operanzi vor avea fiecare câte 4 biți, ceea ce inseamnă că vom avea 16 registre cu care putem lucra (R0 ... R15). Adunând dimensiunile fiecărui câmp, vom obține o instrucțiune pe 16 biți.

Instrucțiunile și codul operațiilor:

Vom considera ca procesorul nostru elementar poate suporta următoarele instrucțiuni:

Operație Cod operație Sintaxă Descriere
ADD 4'b0000 ADD Rd Rs1 Rs2 Rd = Rs1 + Rs2
SUB 4'b0001 SUB Rd Rs1 Rs2 Rd = Rs1 - Rs2
OR 4'b0010 OR Rd Rs1 Rs2 Rd = Rs1 OR Rs2
AND 4'b0011 AND Rd Rs1 Rs2 Rd = Rs1 AND Rs2
LOADC 4'b0100 LOADC Rd Rd = constanta

Pentru instrucțiunile prezentate mai sus, vom avea următoarele moduri de codare (de împărțire a informației în cadrul instrucțiunii):

Codare instructiune.png

Registrele:

Cele 16 registre vor fi codate cu un număr egal cu indexul său. De exemplu, R0 va avea codul 4'b000, R1 va avea codul 4'b0001 și așa mai departe.


Considerând cele spuse mai sus, vom avea următoarele exemple de instrucțiuni:

Exemple codare instructiuni.png


Având toate informațiile de mai sus, descrieți o memorie ROM cu adresă pe 4 biți și locații pe 16 biți, care să conțină următorul program, începând cu adresa 0:

LOADC R0, 2h
LOADC R1, 5h
LOADC R2, 7h
ADD R3, R1, R0
SUB R4, R2, R1
OR R5, R3, R4

Anexa1

Anexa1.PNG