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

Subversion Repositories gpio

[/] [gpio/] [trunk/] [bench/] [verilog/] [wb_master.v] - Blame information for rev 8

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 lampret
`include "timescale.v"
2
 
3
//                              -*- Mode: Verilog -*-
4
// Filename        : wb_master.v
5
// Description     : Wishbone Master Behavorial
6
// Author          : Winefred Washington
7
// Created On      : Thu Jan 11 21:18:41 2001
8
// Last Modified By: .
9
// Last Modified On: .
10
// Update Count    : 0
11
// Status          : Unknown, Use with caution!
12
 
13
//        Description                   Specification
14
// General Description:            8, 16, 32-bit WISHBONE Master
15
// Supported cycles:               MASTER, READ/WRITE
16
//                                 MASTER, BLOCK READ/WRITE
17
//                                 MASTER, RMW
18
// Data port, size:                8, 16, 32-bit
19
// Data port, granularity          8-bit
20
// Data port, Max. operand size    32-bit
21
// Data transfer ordering:         little endian
22
// Data transfer sequencing:       undefined
23
//
24
 
25
module wb_master(CLK_I, RST_I, TAG_I, TAG_O,
26
                   ACK_I, ADR_O, CYC_O, DAT_I, DAT_O, ERR_I, RTY_I, SEL_O, STB_O, WE_O);
27
 
28
   input                CLK_I;
29
   input                RST_I;
30
   input [3:0]           TAG_I;
31
   output [3:0]  TAG_O;
32
   input                ACK_I;
33
   output [31:0]         ADR_O;
34
   output               CYC_O;
35
   input [31:0]  DAT_I;
36
   output [31:0]         DAT_O;
37
   input                ERR_I;
38
   input                RTY_I;
39
   output [3:0]  SEL_O;
40
   output               STB_O;
41
   output               WE_O;
42
 
43
   reg [31:0]            ADR_O;
44
   reg [3:0]             SEL_O;
45
   reg                  CYC_O;
46
   reg                  STB_O;
47
   reg                  WE_O;
48
   reg [31:0]            DAT_O;
49
 
50
   wire [15:0]           mem_sizes;      // determines the data width of an address range
51
   reg [31:0]            write_burst_buffer[0:7];
52
   reg [31:0]            read_burst_buffer[0:7];
53
 
54
   reg                  GO;
55
   integer              cycle_end;
56
   integer              address;
57
   integer              data;
58
   integer              selects;
59
   integer              write_flag;
60
 
61
   //
62
   // mem_sizes determines the data widths of memory space
63
   // The memory space is divided into eight regions. Each
64
   // region is controlled by a two bit field.
65
   //
66
   //    Bits
67
   //    00 = 8 bit memory space
68
   //    01 = 16 bit 
69
   //    10 = 32 bit
70
   //    11 = 64 bit (not supported in this model
71
   //
72
 
73
   assign               mem_sizes = 16'b10_01_10_11_00_01_10_11;
74
 
75
   function [1:0] data_width;
76
      input [31:0] adr;
77
      begin
78
         casex (adr[31:29])
79
           3'b000: data_width = mem_sizes[15:14];
80
           3'b001: data_width = mem_sizes[13:12];
81
           3'b010: data_width = mem_sizes[11:10];
82
           3'b011: data_width = mem_sizes[9:8];
83
           3'b100: data_width = mem_sizes[7:6];
84
           3'b101: data_width = mem_sizes[5:4];
85
           3'b110: data_width = mem_sizes[3:2];
86
           3'b111: data_width = mem_sizes[1:0];
87
           3'bxxx: data_width = 2'bxx;
88
         endcase // casex (adr[31:29])
89
      end
90
   endfunction
91
 
92
   always @(posedge CLK_I or posedge RST_I)
93
     begin
94
        if (RST_I)
95
          begin
96
             GO = 1'b0;
97
          end
98
     end
99
 
100
   // read single
101
   task rd;
102
      input [31:0] adr;
103
      output [31:0] result;
104
 
105
      begin
106
         cycle_end = 1;
107
         address = adr;
108
         selects = 255;
109
         write_flag = 0;
110
 
111
         GO <= 1;
112
         @(posedge CLK_I);
113
//       GO <= 0;        
114
 
115
         // wait for cycle to start
116
         while (~CYC_O)
117
           @(posedge CLK_I);
118
 
119
         // wait for cycle to end
120
         while (CYC_O)
121
           @(posedge CLK_I);
122
 
123
         result = data;
124
//      $display(" Reading %h from address %h", result, address);
125
 
126
      end
127
   endtask // read
128
 
129
   task wr;
130
      input [31:0] adr;
131
      input [31:0] dat;
132
      input [3:0] sel;
133
      begin
134
         cycle_end = 1;
135
         address = adr;
136
         selects = sel;
137
         write_flag = 1;
138
         data = dat;
139
 
140
         GO <= 1;
141
         @(posedge CLK_I);
142
//       GO <= 0;        
143
 
144
         // wait for cycle to start
145
         while (~CYC_O)
146
           @(posedge CLK_I);
147
 
148
         // wait for cycle to end
149
         while (CYC_O)
150
           @(posedge CLK_I);
151
//      $display(" Writing %h to address %h", data, address);
152
 
153
      end
154
   endtask // wr
155
 
156
   // block read
157
   task blkrd;
158
      input [31:0] adr;
159
      input end_flag;
160
      output [31:0] result;
161
 
162
      begin
163
         write_flag = 0;
164
         cycle_end = end_flag;
165
         address = adr;
166
         GO <= 1;
167
         @(posedge CLK_I);
168
//       GO <= 0;        
169
 
170
         while (~(ACK_I & STB_O))
171
           @(posedge CLK_I);
172
 
173
         result = data;
174
      end
175
   endtask // blkrd
176
 
177
   // block write
178
   task blkwr;
179
      input [31:0] adr;
180
      input [31:0] dat;
181
      input [3:0] sel;
182
      input end_flag;
183
      begin
184
         write_flag = 1;
185
         cycle_end = end_flag;
186
         address = adr;
187
         data = dat;
188
         selects = sel;
189
         GO <= 1;
190
         @(posedge CLK_I);
191
//       GO <= 0;        
192
 
193
         while (~(ACK_I & STB_O))
194
           @(posedge CLK_I);
195
 
196
      end
197
   endtask // blkwr
198
 
199
   // RMW
200
   task rmw;
201
      input [31:0] adr;
202
      input [31:0] dat;
203
      input [3:0] sel;
204
      output [31:0] result;
205
 
206
      begin
207
         // read phase
208
         write_flag = 0;
209
         cycle_end = 0;
210
         address = adr;
211
         GO <= 1;
212
         @(posedge CLK_I);
213
//       GO <= 0;        
214
 
215
         while (~(ACK_I & STB_O))
216
           @(posedge CLK_I);
217
 
218
         result = data;
219
 
220
         // write phase
221
         write_flag = 1;
222
         address = adr;
223
         selects = sel;
224
         GO <= 1;
225
         data <= dat;
226
         cycle_end <= 1;
227
         @(posedge CLK_I);
228
//       GO <= 0;        
229
 
230
         while (~(ACK_I & STB_O))
231
           @(posedge CLK_I);
232
 
233
      end
234
   endtask // rmw
235
 
236
   always @(posedge CLK_I)
237
     begin
238
        if (RST_I)
239
          ADR_O <= 32'h0000_0000;
240
        else
241
          ADR_O <= address;
242
     end
243
 
244
   always @(posedge CLK_I)
245
     begin
246
        if (RST_I | ERR_I | RTY_I)
247
          CYC_O <= 1'b0;
248
        else if ((cycle_end == 1) & ACK_I)
249
          CYC_O <= 1'b0;
250
        else if (GO | CYC_O) begin
251
          CYC_O <= 1'b1;
252
          GO <= 1'b0;
253
        end
254
     end
255
 
256
   // stb control
257
   always @(posedge CLK_I)
258
     begin
259
        if (RST_I | ERR_I | RTY_I)
260
          STB_O <= 1'b0;
261
        else if (STB_O & ACK_I)
262
          STB_O <= 1'b0;
263
        else if (GO | STB_O)
264
          STB_O <= 1'b1;
265
     end
266
 
267
   // selects & data
268
   always @(posedge CLK_I)
269
     begin
270
        if (write_flag == 0) begin
271
           SEL_O <= 4'b1111;
272
           if (STB_O & ACK_I)
273
             data <= DAT_I;
274
        end
275
        else begin
276
           case (data_width(address))
277
             2'b00: begin
278
                SEL_O <= {3'b000, selects[0]};
279
                DAT_O <= {data[7:0], data[7:0], data[7:0], data[7:0]};
280
             end
281
             2'b01: begin
282
                SEL_O <= {2'b00, selects[1:0]};
283
                DAT_O <= {data[15:0], data[15:0]};
284
             end
285
             2'b10: begin
286
                SEL_O <= selects;
287
                DAT_O <= data;
288
             end
289
           endcase
290
        end
291
     end
292
 
293
   always @(posedge CLK_I)
294
     begin
295
        if (RST_I)
296
          WE_O <= 1'b0;
297
        else if (GO)
298
          WE_O <= write_flag;
299
     end
300
 
301
endmodule
302
 
303
 
304
 
305
 
306
 

powered by: WebSVN 2.1.0

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