Verilog код для оперативной памяти - PullRequest
0 голосов
/ 23 июня 2018

Я пытаюсь смоделировать следующий код для асинхронного оперативной памяти в Verilog.Но dout остается хххх все время.В первый раз, когда я попробовал код dout был равен din для времени, когда сигнал записи был 1. После того, как это было все xxxx. Может кто-нибудь сказать мне проблему? Было бы здорово, если бы вы могли предложить лучшекод.

module ram(cs,wr,addr,din,dout);
parameter adds = 10, wsize =16, memsize =1024;
input cs,wr;
input [adds-1:0] addr;
 input [wsize-1 : 0]din;
 output [wsize-1:0]dout;
reg [wsize-1:0] mem [memsize-1:0];
assign dout = mem[addr];
always @(cs or wr)
begin
if(wr) mem[addr]= din;
end
endmodule

Стенд для вышеуказанного кода:

module ramtest;

// Inputs
reg cs;
reg wr;
reg [9:0] addr;
reg [15:0] din;

// Outputs
wire [15:0] dout;
integer k,myseed;

// Instantiate the Unit Under Test (UUT)
ram uut (
    .cs(cs), 
    .wr(wr), 
    .addr(addr), 
    .din(din), 
    .dout(dout)
);

initial begin
for(k = 0; k<=1023; k = k+1)
 begin
 din = k % 256; wr = 1; cs= 1;addr= k ;
 end

repeat(20)
begin
#2 addr = $random(myseed) % 1024 ;
wr = 0; cs =1;
$display("Address = %5d, data = %4d",addr,dout);
end
end

initial myseed = 35 ; 

endmodule

1 Ответ

0 голосов
/ 23 июня 2018

Несколько ошибок:

  1. Ваши wr и cs не меняются, поэтому всегда @ (cs или wr) вводится только один раз для записи и один раз для чтения.
  2. Ваш код записи в тестовом стенде for(k = 0; k<=1023; k = k+1) не имеет задержки.Таким образом, на самом деле нет времени для записи.

Однако самая большая опасность состоит в том, что вы «просто» добавляете адрес в список чувствительности, и все это «работает»:
always @(cs or wr or addr)

Вероятно, это помогло бы вам, если бы вы сначала просмотрели таблицу асинхронного ОЗУ.Они не работают так, как вы это моделируете.Там данные сохраняются, когда CS или запись исчезают (что когда-либо раньше).Данные и адрес должны быть стабильными в определенное время до и после этого.

В вашей модели вы меняете адрес, сохраняя активными WR и CS.В реальной жизни адрес не меняется мгновенно от одного значения к другому.Например, оно будет изменяться с 0000 на 000F, но биты будут меняться по одному: 0000 => 0004 => 0005 => 000D ==> 000F.Таким образом, вы могли испортить содержимое 5 разных адресов.

Сделать сигнал записи из CS и WR: do_write = cs & wr; Выполнить реальную запись, когда этот сигнал исчезнет: всегда @ (negedge do_write) .....`.

...