512x8存储器模型。端口信号为:addr[8:0], wrena, wrdata[7:0], rddata[7:0]. 存储器用wrena信号的上升沿将数据写入。再写一个测试台, 做以下检测:
(1) 将所有地址都写0;
(2) 检查每个地址是否读0;
(3) 将所有地址都写8’hff;
(4) 检查每个地址是否读8’hff;
(5) 每个地址先写8’h55,读,再写8’haa,再读。重复所有地址。
如果有错误立即停止执行,并打印出错信息。
/***********************************************************
* File: m512x8.v
* Description: This module is a model of 512x8 memory
************************************************************/
module m512x8 (addr, wrena, wrdata, rddata);
input[8:0] addr; // address bus
input wrena; // write enable
input[7:0] wrdata; // data to write into memory
output[7:0] rddata; // data read from memory
reg[7:0] mem[0:511]; // memory declaration
integer i; // loop variable
wire validaddr = ^addr===1'b1 || ^addr===1'b0;
always @(posedge wrena) begin
if(validaddr) mem[addr] = wrdata;
else begin
for(i=0;i<512;i=i+1)
if((&(addr^i[8:0]))===1'b0 && (|(addr^i[8:0]))!==1'b1)
mem[i] = ((mem[i]^wrdata) & 8'hxx) ^ mem[i];
end
end
assign rddata = (validaddr)? mem[addr]:8'hxx;
endmodule
/*************************************************************
* File: mtest.v
* Description: This module is a test bench to test
* a memory model.
*************************************************************/
`timescale 1ns/1ns
module mtest;
reg wrena; // write enable
reg[8:0] addr; // address
reg[7:0] wrdata, // write data
data; // temporary data register
wire[7:0] rddata; // read data
integer i; // loop variable
m512x8 mem(.addr(addr), .wrena(wrena), .wrdata(wrdata),
.rddata(rddata));
initial begin
$vcdpluson;
wrena = 1;
addr = 9'bx;
wrdata = 8'bx;
$write($stime,,"Test 1: Write 0 to all addresses........");
for(i=0;i<512;i=i+1) writem(i,8'd0);
$display("Done.");
$write($stime,,"Test 2: Check data for every address....");
for(i=0;i<512;i=i+1) begin
readm(i,data);
if(data!==8'd0) begin
$display(""); // \n
$display($stime,,"Error: Data read = %X, expected=00",data);
#20 $finish;
end
end
$display("Done.");
$write($stime,,"Test 3: Write FF to all addresses.......");
for(i=0;i<512;i=i+1) writem(i,8'hff);
$display("Done.");
$write($stime,,"Test 4: Check data for every address....");
for(i=0;i<512;i=i+1) begin
readm(i,data);
if(data!==8'hff) begin
$display(""); // \n
$display($stime,,"Error: Data read = %X, expected=FF",data);
#20 $finish;
end
end
$display("Done.");
$write($stime,,"Test 5: Write and read test.............");
for(i=0;i<512;i=i+1) begin
writem(i,8'h55); // write 55 first
readm(i,data);
if(data!==8'h55) begin
$display(""); // \n
$display($stime,,"Error: Data read = %X, expected=55",data);
#20 $finish;
end
writem(i,8'hAA); // write AA this time
readm(i,data);
if(data!==8'haa) begin
$display(""); // \n
$display($stime,,"Error: Data read = %X, expected=AA",data);
#20 $finish;
end
end
$display("Done.");
#20 $finish;
end
task writem; // task to write memory
input[8:0] ad; // address to write
input[7:0] data; // data to write
begin
addr = ad;
wrena = 0;
#10
wrdata = data;
#10
wrena = 1;
#5
addr = 9'bx;
wrdata = 8'bx;
#5; // delay to separate operations
end
endtask
task readm; // task to read memory
input[8:0] ad; // address to read
output[7:0] data; // data read from memory
begin
addr = ad;
#10 data = rddata;
#5 addr = 8'bx;
#5; // wait 5ns before next operation
end
endtask
endmodule