OpenCores
URL https://opencores.org/ocsvn/sdram_16bit/sdram_16bit/trunk

Subversion Repositories sdram_16bit

[/] [sdram_16bit/] [trunk/] [testbench/] [wb_master.sv] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ultra_embe
//-----------------------------------------------------------------
2
// Module
3
//-----------------------------------------------------------------
4
module wb_master
5
(
6
    input                               clk_i,
7
    input                               rst_i,
8
 
9
    // Wishbone I/F
10
    output reg [31:0]                   addr_o,
11
    output reg [31:0]                   data_o,
12
    input [31:0]                        data_i,
13
    output reg [3:0]                    sel_o,
14
    output reg [2:0]                    cti_o,
15
    output reg                          cyc_o,
16
    output reg                          stb_o,
17
    output reg                          we_o,
18
    input                               ack_i,
19
    input                               stall_i
20
);
21
 
22
//-----------------------------------------------------------------
23
// Params
24
//-----------------------------------------------------------------
25
parameter MIN_ADDRESS       = 0;
26
parameter MAX_ADDRESS       = 8192;
27
parameter BURST_ENABLED     = 1;
28
parameter READ_ONLY         = 0;
29
parameter WRITE_ONLY        = 0;
30
parameter SEQUENTIAL_ONLY   = 0;
31
parameter RANDOM_DELAY      = 1;
32
parameter DELAY_RATE        = 3;
33
 
34
`include "simulation.svh"
35
 
36
//-----------------------------------------------------------------
37
// Request Queue
38
//-----------------------------------------------------------------
39
typedef struct
40
{
41
    reg [31:0] address;
42
    reg [31:0] data;
43
    reg [3:0]  sel;
44
    reg        we;
45
} request_t;
46
 
47
request_t requests[$];
48
 
49
//-----------------------------------------------------------------
50
// Memory
51
//-----------------------------------------------------------------
52
reg [31:0] mem[*];
53
 
54
//-----------------------------------------------------------------
55
// write
56
//-----------------------------------------------------------------
57
task automatic write(input [31:0] addr, input [31:0] data);
58
begin
59
    mem[addr[31:2]] = data;
60
end
61
endtask
62
 
63
//-----------------------------------------------------------------
64
// read
65
//-----------------------------------------------------------------
66
task automatic read(input [31:0] addr, output [31:0] data);
67
begin
68
    if (mem.exists(addr[31:2]))
69
        data = mem[addr[31:2]];
70
    else
71
        data = 32'bx;
72
end
73
endtask
74
 
75
//-----------------------------------------------------------------
76
// write_bytes
77
//-----------------------------------------------------------------
78
task automatic write_bytes(input [31:0] addr, input [31:0] data, input [31:0] sel);
79
begin
80
    reg [31:0] new_data;
81
 
82
    read(addr, new_data);
83
 
84
    if (sel[3])
85
        new_data[31:24] = data[31:24];
86
    if (sel[2])
87
        new_data[23:16] = data[23:16];
88
    if (sel[1])
89
        new_data[15:8]  = data[15:8];
90
    if (sel[0])
91
        new_data[7:0]   = data[7:0];
92
 
93
    write(addr, new_data);
94
end
95
endtask
96
 
97
//-----------------------------------------------------------------
98
// compare
99
//-----------------------------------------------------------------
100
task automatic compare(input [31:0] addr, input [31:0] data, input [31:0] sel, output match);
101
begin
102
    reg [31:0] new_data;
103
 
104
    read(addr, new_data);
105
 
106
    match = 1;
107
 
108
    if (sel[3])
109
        if (new_data[31:24] !== data[31:24])
110
            match = 0;
111
 
112
    if (sel[2])
113
        if (new_data[23:16] !== data[23:16])
114
            match = 0;
115
 
116
    if (sel[1])
117
        if (new_data[15:8] !== data[15:8])
118
            match = 0;
119
 
120
    if (sel[0])
121
        if (new_data[7:0] !== data[7:0])
122
            match = 0;
123
 
124
    if (!match)
125
    begin
126
        $display("ERROR: Expected %x Got %x Mask %x", new_data, data, sel);
127
    end
128
end
129
endtask
130
 
131
//-----------------------------------------------------------------
132
// request
133
//-----------------------------------------------------------------
134
initial
135
begin
136
    request_t  req;
137
    reg        burst;
138
    reg [2:0]  burst_cnt;
139
 
140
    addr_o = 32'bz;
141
    data_o = 32'bz;
142
    sel_o  = 4'bz;
143
    we_o   = 1'bz;
144
    stb_o  = 1'b0;
145
    cti_o  = 3'bz;
146
    burst  = 1'b0;
147
    burst_cnt = 0;
148
 
149
    req.address = 0;
150
 
151
    forever
152
    begin
153
        @(posedge clk_i);
154
 
155
        // Command presented and accepted
156
        if (stb_o && !stall_i)
157
        begin
158
            requests.push_back(req);
159
 
160
            addr_o = 32'bz;
161
            data_o = 32'bz;
162
            sel_o  = 4'bz;
163
            we_o   = 1'bz;
164
            cti_o  = 3'bz;
165
            stb_o  = 1'b0;
166
        end
167
 
168
        // Continuation of a burst
169
        if (!stb_o && burst)
170
        begin
171
            req.address = req.address + 4;
172
            req.data    = req.we ? $urandom : 32'bz;
173
 
174
            addr_o = req.address;
175
            addr_o[1:0] = 2'b0;
176
            data_o = req.data;
177
            cti_o  = (burst_cnt == 1) ? 3'b111 : 3'b010;
178
            sel_o  = req.sel;
179
            we_o   = req.we;
180
            stb_o  = 1'b1;
181
 
182
            burst_cnt   = burst_cnt - 1;
183
            if (burst_cnt == 0)
184
                burst   = 0;
185
        end
186
 
187
        // Ready to issue a new command?
188
        if (!stb_o)
189
        begin
190
 
191
            if (RANDOM_DELAY)
192
            begin
193
                repeat ($urandom_range(DELAY_RATE,0)) @(posedge clk_i);
194
            end
195
 
196
            if (SEQUENTIAL_ONLY)
197
                req.address = req.address + 4;
198
            else
199
                req.address = $urandom_range(MAX_ADDRESS,MIN_ADDRESS);
200
 
201
            if (READ_ONLY)
202
                req.we  = 1'b0;
203
            else if (WRITE_ONLY)
204
                req.we  = 1'b1;
205
            else
206
                req.we  = $urandom;
207
            req.data    = req.we ? $urandom : 32'bz;
208
 
209
            if (BURST_ENABLED)
210
            begin
211
                burst       = $urandom;
212
                burst_cnt   = 7;
213
            end
214
            else
215
                burst       = 0;
216
 
217
            req.sel     = (!burst && req.we) ? $urandom : 4'b1111;
218
 
219
            addr_o = req.address;
220
            addr_o[1:0] = 2'b0;
221
            data_o = req.data;
222
            sel_o  = req.sel;
223
            we_o   = req.we;
224
            cti_o  = (!burst) ? 3'b111 : 3'b010;
225
            stb_o  = 1'b1;
226
        end
227
    end
228
end
229
 
230
//-----------------------------------------------------------------
231
// response
232
//-----------------------------------------------------------------
233
always @(posedge clk_i)
234
begin
235
    request_t  req;
236
    if (ack_i)
237
    begin
238
        `ASSERT(requests.size() > 0);
239
 
240
        req = requests.pop_front();
241
 
242
        // Write
243
        if (req.we)
244
        begin
245
            write_bytes(req.address, req.data, req.sel);
246
        end
247
        // Read
248
        else
249
        begin
250
            reg match;
251
            compare(req.address, data_i, req.sel, match);
252
            `ASSERT(match);
253
        end
254
    end
255
end
256
 
257
always @ *
258
begin
259
    cyc_o  = stb_o || (requests.size() > 0);
260
end
261
 
262
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.