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

Subversion Repositories gpio

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

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

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

powered by: WebSVN 2.1.0

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