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

Subversion Repositories ftdi_wb_bridge

[/] [ftdi_wb_bridge/] [trunk/] [testbench/] [wb_slave.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_slave
5
(
6
    input                               clk_i /*verilator public*/,
7
    input                               rst_i /*verilator public*/,
8
 
9
    // Wishbone I/F
10
    input [31:0]                        addr_i /*verilator public*/,
11
    input [31:0]                        data_i /*verilator public*/,
12
    output reg [31:0]                   data_o /*verilator public*/,
13
    input [3:0]                         sel_i /*verilator public*/,
14
    input                               cyc_i /*verilator public*/,
15
    input                               stb_i /*verilator public*/,
16
    input [2:0]                         cti_i /*verilator public*/,
17
    input                               we_i /*verilator public*/,
18
    output reg                          ack_o /*verilator public*/,
19
    output reg                          stall_o /*verilator public*/
20
);
21
 
22
//-----------------------------------------------------------------
23
// Params
24
//-----------------------------------------------------------------
25
parameter MAX_RESP_RATE     = 0;
26
parameter RESP_DELAY_RATE   = 3;
27
 
28
parameter RANDOM_STALLS     = 1;
29
parameter STALL_RATE        = 3;
30
 
31
`include "simulation.svh"
32
 
33
//-----------------------------------------------------------------
34
// Request Queue
35
//-----------------------------------------------------------------
36
typedef struct
37
{
38
    reg [31:0] address;
39
    reg [31:0] data;
40
    reg [3:0]  sel;
41
    reg        we;
42
} request_t;
43
 
44
request_t requests[$];
45
 
46
//-----------------------------------------------------------------
47
// Memory
48
//-----------------------------------------------------------------
49
reg [31:0] mem[*];
50
 
51
//-----------------------------------------------------------------
52
// write
53
//-----------------------------------------------------------------
54
task automatic write(input [31:0] addr, input [31:0] data);
55
begin
56
    mem[addr[31:2]] = data;
57
end
58
endtask
59
 
60
//-----------------------------------------------------------------
61
// read
62
//-----------------------------------------------------------------
63
task automatic read(input [31:0] addr, output [31:0] data);
64
begin
65
    if (mem.exists(addr[31:2]))
66
        data = mem[addr[31:2]];
67
    else
68
        data = 32'bx;
69
end
70
endtask
71
//-----------------------------------------------------------------
72
// read8
73
//-----------------------------------------------------------------
74
task automatic read8(input [31:0] addr, output [7:0] data);
75
begin
76
    if (mem.exists(addr[31:2]))
77
    begin
78
        reg [31:0] tmp_data;
79
        tmp_data = mem[addr[31:2]];
80
 
81
        case (addr[1:0])
82
            0: data = tmp_data[7:0];
83
            1: data = tmp_data[15:8];
84
            2: data = tmp_data[23:16];
85
            3: data = tmp_data[31:24];
86
        endcase
87
    end
88
    else
89
        data = 8'bx;
90
end
91
endtask
92
//-----------------------------------------------------------------
93
// write_bytes
94
//-----------------------------------------------------------------
95
task automatic write_bytes(input [31:0] addr, input [31:0] data, input [31:0] sel);
96
begin
97
    reg [31:0] new_data;
98
 
99
    read(addr, new_data);
100
 
101
    if (sel[3])
102
        new_data[31:24] = data[31:24];
103
    if (sel[2])
104
        new_data[23:16] = data[23:16];
105
    if (sel[1])
106
        new_data[15:8]  = data[15:8];
107
    if (sel[0])
108
        new_data[7:0]   = data[7:0];
109
 
110
    write(addr, new_data);
111
end
112
endtask
113
 
114
//-----------------------------------------------------------------
115
// response
116
//-----------------------------------------------------------------
117
initial
118
begin
119
    request_t  req;
120
 
121
    ack_o  = 1'b0;
122
    data_o = 32'bz;
123
 
124
    forever
125
    begin
126
        @(posedge clk_i);
127
 
128
        ack_o  = 1'b0;
129
        data_o = 32'bz;
130
 
131
        if (!MAX_RESP_RATE)
132
        begin
133
            repeat ($urandom_range(RESP_DELAY_RATE,0)) @(posedge clk_i);
134
        end
135
 
136
        if (requests.size() > 0)
137
        begin
138
            req = requests.pop_front();
139
 
140
            // Write
141
            if (req.we)
142
            begin
143
                ack_o  = 1'b1;
144
                data_o = 32'bz;
145
 
146
                write_bytes(req.address, req.data, req.sel);
147
            end
148
            // Read
149
            else
150
            begin
151
                ack_o  = 1'b1;
152
                read(req.address, data_o);
153
            end
154
        end
155
    end
156
end
157
 
158
//-----------------------------------------------------------------
159
// request
160
//-----------------------------------------------------------------
161
always @(posedge clk_i)
162
begin
163
    // Request presented and accepted
164
    if (stb_i && cyc_i && !stall_o)
165
    begin
166
        request_t req;
167
 
168
        req.address = addr_i;
169
        req.data    = data_i;
170
        req.sel     = sel_i;
171
        req.we      = we_i;
172
 
173
        requests.push_back(req);
174
    end
175
end
176
 
177
always @(posedge rst_i or posedge clk_i)
178
if (rst_i)
179
    stall_o <= 1'b0;
180
else
181
begin
182
    if (RANDOM_STALLS)
183
        stall_o <= ($urandom_range(STALL_RATE,0) == 0);
184
end
185
 
186
//-----------------------------------------------------------------
187
// CTI
188
//-----------------------------------------------------------------
189
initial
190
begin
191
    reg        burst;
192
    reg [2:0]  burst_cnt;
193
 
194
    burst  = 1'b0;
195
    burst_cnt = 0;
196
 
197
    forever
198
    begin
199
        @(posedge clk_i);
200
 
201
        // Start of burst
202
        if (stb_i && cyc_i && !stall_o && cti_i == 3'b010)
203
        begin
204
            burst_cnt = 7;
205
            burst = 1;
206
 
207
            while (burst_cnt != 0)
208
            begin
209
                @(posedge clk_i);
210
 
211
                if (stb_i && cyc_i && !stall_o)
212
                begin
213
                    if (burst_cnt == 1)
214
                    begin
215
                        `ASSERT(cti_i == 3'b111);
216
                    end
217
 
218
                    burst_cnt = burst_cnt - 1;
219
                end
220
            end
221
 
222
            burst = 0;
223
        end
224
        else if (stb_i && cyc_i && !stall_o)
225
        begin
226
            `ASSERT(cti_i == 3'b111);
227
        end
228
    end
229
end
230
 
231
endmodule

powered by: WebSVN 2.1.0

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