mem.v
2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// mem.v
// common memory/cpu tasks;
// :set tabstop=4
// monitor memory backdoor;
reg mem_mon;
reg mirror;
initial
begin
$display("%M: ri_model memory backdoor");
mem_mon = $test$plusargs("mem_mon");
mirror = 0;
end
// make single byte mask from address and size;
function [31:0] sgl_mask;
input [1:0] addr; // requests address;
input [1:0] size; // request size;
reg [31:0] mask; // data compare mask;
begin
case({size,addr})
4'b0000: mask = 32'hff000000;
4'b0001: mask = 32'h00ff0000;
4'b0010: mask = 32'h0000ff00;
4'b0011: mask = 32'h000000ff;
4'b0100: mask = 32'hffff0000;
4'b0110: mask = 32'h0000ffff;
4'b1000: mask = 32'hffffff00;
4'b1001: mask = 32'h00ffffff;
4'b1100: mask = 32'hffffffff;
default: begin
mask = 32'h00000000;
$display("ERROR: %t: %M: illegal addr %b, size %b", $time, addr, size);
end
endcase
sgl_mask = mask;
end
endfunction
// check memory address;
// 0x8000_0000 ... 0xffff_ffff x64 high space, 2GBytes;
// 0x0100_0000 ... 0x02ff_ffff x64 low space, 32MBytes;
// 0x0000_0000 ... 0x00ff_ffff x36 space, lower 16MBytes;
task mem_check_addr;
input [31:0] addr; // address, possibly mirrored;
input mirror; // enable mirror mapping;
output x36; // is a x36 address;
output valid; // address is valid;
reg [31:24] spc;
integer size;
begin
spc = addr[31:24];
valid = 0;
if(spc === 'h00) begin
valid = 1;
x36 = 1;
end else if((spc === 'h01) | (spc === 'h02)) begin
valid = 1;
x36 = 0;
addr[31:24] = addr[31:24] - 1;
end else if(spc[31] === 1) begin
valid = (spc[31:30] == 2'b10);
x36 = 0;
addr[31] = 0;
end
if(valid) begin
size = MEM_SIZE;
if(x36)
size = size >> 1;
if(!mirror & (addr >= size))
valid = 0;
end
if( !valid)
$display("ERROR: %t: ri: addr 0x%h outside memory", $time, addr);
end
endtask
task mem_check9;
input [31:0] addr;
input [31:0] words;
integer i;
reg [31:0] check_addr;
reg [31:0] word0, word1;
begin
check_addr = addr & 32'hFFFFFFFC;
if (addr < 32'h01000000) begin /* x36 space */
for (i=0; i< words; i=i+1) begin
mem_sread(check_addr, 3, word0);
mem_sread(((check_addr<<1) | 32'h01000000) + 4, 3, word1);
if (word0[0] !== word1[0] || word0[0] != word1[8] ||
word0[16] !== word1[16] || word0[16] != word1[24]) begin
$display("ERROR: %t 9th bits wrong 0x%x <0x%x> at",
$time, word0, word1, check_addr );
end
check_addr = check_addr + 4;
end
end
end
endtask