CID Aplicatii 11

De la WikiLabs
Versiunea din 29 aprilie 2021 11:28, autor: Gvpopescu (discuție | contribuții) (Pagină nouă: ==1. Memoria FIFO == Memoria FIFO este o structura de memorare ce respecta regula First-In First-Out. Asadar, din aceasta memorie se va citi mereu cea mai veche data scrisa. Struct...)
(dif) ← Versiunea anterioară | Versiunea curentă (dif) | Versiunea următoare → (dif)
Jump to navigationJump to search

1. Memoria FIFO

Memoria FIFO este o structura de memorare ce respecta regula First-In First-Out. Asadar, din aceasta memorie se va citi mereu cea mai veche data scrisa. Structura interna a acestui circuit este prezentata in figura urmatoare.

Dupa cum se poate observa, nu mai este nevoie de magistrale de adrese pentru scriere si pentru citire. Acestea sunt calculate intern cu ajutorul unor numaratoare cu enable (WRITE_PTR si READ_PTR). Pentru usurinta intelegerii, putem privi FIFO ca o memorie circulara, cu adrese de citire si scriere ce se „urmaresc” una pe cealalta. Memoria tinde spre „umplere” prin scrieri si spre „golire” prin citiri:

FIFO descris mai sus are trei semnale de feedback:

  • fifo_counter, care ne spune cate locatii de memorie din cele totale sunt ocupate.
  • empty, activ atunci cand memoria este goala (0 locatii de memorie ocupate)
  • full, activ atunci cand toate locatiile sunt ocupate. Citirea este blocata din momentul in care full devine activ pana se elibereaza locatii prin citire.

Semnalele write_enable si read_enable care sunt transmise modulului din exterior nu pot ajunge direct la memorie deoarece trebuie impiedicate scrierile sau citirile eronate: o citire eronata apare atunci cand se incearca citirea dintr-o memorie goala, iar o scriere eronata apare atunci cand se incearca scrierea intr-o memorie complet ocupata. De aceea, semnalul real de comanda a scrierii (wr_en_mem) este activ doar daca se declanseaza o scriere si memoria nu este plina, iar semnalul real de citire (rd_en_mem) este activ doar daca se declanseaza o citire dintr-o memorie care nu este goala.

Principalele blocuri ale memoriei FIFO sunt:

  • RAMDP: memorie dual-port, cu citire sincrona. Acesta este elementul de memorare efectiva.
  • WRITE_PTR: numarator ce incrementeaza adresa de scriere, daca apare o scriere valida (wr_en_mem este 1).
  • READ_PTR: numarator ce incrementeaza adresa de citire, daca apare o citire valida (rd_en_mem este 1).
  • FIFO_COUNTER: numarator ce contorizeaza locatiile ocupate: se incrementeaza daca are loc o scriere fara citire (wr_en_mem este 1 si rd_en_mem este 0) si se decrementeaza daca are loc o citire fara scriere (rd_en_mem este 1 si wr_en_mem este 0).
  • CONTROL: modul combinational care genereaza semnalele de control: empty, full, wr_en_mem si rd_en_mem, cu functionalitatile descrise anterior.


Implementarea memoriei RAMDP

module RAMDP
#( parameter DATA_W = 8, ADDR_W = 5)
(
    input clock,
    input read_enable,
    input write_enable,
    input [ADDR_W-1:0] addr_read,
    input [ADDR_W-1:0] addr_write,
    input [DATA_W-1:0] data_in,
    output reg [DATA_W-1:0] data_out
);

reg [DATA_W-1:0] memory [0:2**ADDR_W-1];

always@(posedge clock) begin
    if(write_enable)
        memory[addr_write] <= data_in;
    if(read_enable)
        data_out <= memory[addr_read];
end

endmodule

Implementarea memoriei FIFO

module FIFO
#( parameter DATA_W = 8, ADDR_W = 5)
( 
    input clock, reset, // semnal de ceas si reset
    input write_enable, // comanda de scriere
    input read_enable, // comanda de citire
    input [DATA_W-1 : 0] data_in, // date de intrare
    output [DATA_W-1 : 0] data_out, // date de iesire
    output empty, // semnal activ cand memoria este goala
    output full, // semnal activ cand memoria este plina
    output reg [ADDR_W:0] fifo_counter 	//nr locatii folosite
 );
 wire rd_en_mem, wr_en_mem;
 reg [ADDR_W-1:0] write_ptr_reg, read_ptr_reg;
 
 //WRITE POINTER	
 always@(posedge clock) begin
    if(reset == 0)
        write_ptr_reg <= 0;
    else if (wr_en_mem == 1)
        write_ptr_reg <= write_ptr_reg + 1;
 end
 
 //READ POINTER	
 always@(posedge clock) begin
    if(reset == 0)
        read_ptr_reg <= 0;
    else if (rd_en_mem == 1)
        read_ptr_reg <= read_ptr_reg + 1;
 end
 
 //FIFO COUNTER
 always@(posedge clock) begin
    if(reset == 0)
        fifo_counter <= 0;
    else if (rd_en_mem && !wr_en_mem)
        fifo_counter <= fifo_counter - 1;
    else if (!rd_en_mem && wr_en_mem)
        fifo_counter <= fifo_counter + 1;	
 end
 
 //READ_ENABLE AND WRITE_ENABLE
 assign wr_en_mem = write_enable & ~full;
 assign rd_en_mem = read_enable & ~empty;
 
 //FULL AND EMPTY
 assign full  = (fifo_counter == 2**ADDR_W);
 assign empty = (fifo_counter == 0);

 RAMDP #(.DATA_W(DATA_W), .ADDR_W(ADDR_W)) MEM(
    .clock(clock),
    .read_enable(rd_en_mem),
    .write_enable(wr_en_mem),
    .addr_read(read_ptr_reg),
    .addr_write(write_ptr_reg),
    .data_in(data_in),
    .data_out(data_out)
 );
 
 endmodule

Implementarea unui test bench pentru memoria FIFO

`timescale 1ns/1ps

module FIFO_TB;

parameter DATA_W_T = 8;
parameter ADDR_W_T = 5;

reg clock_t, reset_t;
reg write_enable_t, read_enable_t;
reg [DATA_W_T-1 : 0] data_in_t; 
wire [DATA_W_T-1 : 0] data_out_t;
wire empty_t, full_t;
wire [ADDR_W_T:0] fifo_counter_t;

integer i;
integer j;

initial begin
       reset_t = 0;
    #2 reset_t = 1;
       read_enable_t = 0;
       for(j = 0; j<= 2**ADDR_W_T; j = j + 1) begin //umplem complet FIFO. La final, semnalul full va deveni HIGH
           #2;
           data_in_t = j;
           write_enable_t = 1;
       end
    #2 read_enable_t = 1;
       write_enable_t = 0; //pornim citirea pana cand FIFO se va goli complet, iar semnalul empty va deveni HIGH
       #80 $stop();

end

initial begin
    clock_t = 0;
    forever #1 clock_t = ~clock_t;
end

FIFO #(.DATA_W(DATA_W_T), .ADDR_W(ADDR_W_T)) DUT( 
    .clock(clock_t), 
    .reset(reset_t), 
    .write_enable(write_enable_t), 
    .read_enable(read_enable_t), 
    .data_in(data_in_t), 
    .data_out(data_out_t), 
    .empty(empty_t), 
    .full(full_t), 
    .fifo_counter(fifo_counter_t) 	

 );

endmodule

2. Module descrise recursiv