L'inserimento di un banco di memoria all'interno di un progetto può essere molto utile per verificare la corretta comunicazione tra l'FPGA e una memoria esterna. Per fare ciò si può descrivere la memoria direttamente nel test bench, per poi instanziarla ed effettuare i vari collegamenti.
`timescale 1ns / 1ns
module prova_tb ;
reg clk ;
wire ce_l, we_l, oe_l;
wire [15:0] data, address;
reg reset ;
prova DUT (
.clk (clk) ,
.reset (reset ) ,
.ce_l(ce_l),
.we_l(we_l),
.oe_l(oe_l),
.sram_add(address),
.sram_data(data)
);
sram_chip sram (
.Address(address),
.Data(data),
.CS(ce_l),
.WE(we_l),
.OE(oe_l)
);
.
.
.
Corpo del test bench
.
.
.
initial
#4000000 $stop;
endmodule
module sram_chip (Address, Data, CS, WE, OE);
parameter AddressSize = 16;
parameter WordSize = 16;
input [AddressSize-1:0] Address;
inout [WordSize-1:0] Data;
input CS, WE, OE;
reg [WordSize-1:0] Mem [0:1<<AddressSize];
assign Data = (!CS && !OE) ? Mem[Address] : {WordSize{1'bz}};
always @( Address)
if (!CS && !WE)
Mem[Address] = Data;
endmodule
In questo esempio la memoria è composta da celle a 16 bit e viene indirizzata con indirizzi della stessa lunghezza.
Una descrizione di questo tipo può essere molto utile anche nelle simulazioni timing e non solo in quelle funzionali. Si posso infatti inserire eventuali ritardi di risposta della memoria, sia in lettura che in scrittura, inserendo gli opportuni ritardi:
module sram_chip (Address, Data, CS, WE, OE);
parameter AddressSize = 16;
parameter WordSize = 16;
input [AddressSize-1:0] Address;
inout [WordSize-1:0] Data;
input CS, WE, OE;
reg [WordSize-1:0] Mem [0:1<<AddressSize];
reg [15:0] data1;
assign Data = (!CS && !OE) ? data1 : {WordSize{1'bz}};
always @( Address)
if (!CS && !WE)
data1 = #10 Mem[Address] ;
always @( Address)
if (!CS && !WE)
Mem[Address] = #5 Data;
endmodule
In questo modo ho imposto un ritardo in lettura di 10 unità di tempo (nel nostro caso ns) e un ritardo in scrittura di 5 unità di tempo.
Nessun commento:
Posta un commento