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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [opencores/] [spi/] [simple_spi_top.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
`timescale 1ns / 10ps
2
 
3
/////////////////////////////////////////////////////////////////////
4
////                                                             ////
5
//// FIFO 4 entries deep                                         ////
6
////                                                             ////
7
//// Authors: Rudolf Usselmann, Richard Herveille                ////
8
////          rudi@asics.ws     richard@asics.ws                 ////
9
////                                                             ////
10
////                                                             ////
11
//// Download from: http://www.opencores.org/projects/sasc       ////
12
////                http://www.opencores.org/projects/simple_spi ////
13
////                                                             ////
14
/////////////////////////////////////////////////////////////////////
15
////                                                             ////
16
//// Copyright (C) 2000-2002 Rudolf Usselmann, Richard Herveille ////
17
////                         www.asics.ws                        ////
18
////                         rudi@asics.ws, richard@asics.ws     ////
19
////                                                             ////
20
//// This source file may be used and distributed without        ////
21
//// restriction provided that this copyright statement is not   ////
22
//// removed from the file and that any derivative work contains ////
23
//// the original copyright notice and the associated disclaimer.////
24
////                                                             ////
25
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
26
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
27
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
28
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
29
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
30
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
31
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
32
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
33
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
34
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
35
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
36
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
37
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
38
////                                                             ////
39
/////////////////////////////////////////////////////////////////////
40
 
41
//  CVS Log
42
//
43
//  $Id: simple_spi_top.v,v 1.2 2006/12/04 14:40:35 tame Exp $
44
//
45
//  $Date: 2006/12/04 14:40:35 $
46
//  $Revision: 1.2 $
47
//  $Author: tame $
48
//  $Locker:  $
49
//  $State: Exp $
50
//
51
 
52
// synopsys translate_off
53
//`include "timescale.v"
54
// synopsys translate_on
55
 
56
 
57
// 4 entry deep fast fifo
58
module fifo4(clk, rst, clr,  din, we, dout, re, full, empty);
59
 
60
parameter dw = 8;
61
 
62
input           clk, rst;
63
input           clr;
64
input   [dw:1]  din;
65
input           we;
66
output  [dw:1]  dout;
67
input           re;
68
output          full, empty;
69
 
70
 
71
////////////////////////////////////////////////////////////////////
72
//
73
// Local Wires
74
//
75
 
76
reg     [dw:1]  mem[0:3];
77
reg     [1:0]   wp;
78
reg     [1:0]   rp;
79
wire    [1:0]   wp_p1;
80
wire    [1:0]   wp_p2;
81
wire    [1:0]   rp_p1;
82
wire            full, empty;
83
reg             gb;
84
 
85
////////////////////////////////////////////////////////////////////
86
//
87
// Misc Logic
88
//
89
 
90
always @(posedge clk or negedge rst)
91
        if(!rst)        wp <= #1 2'h0;
92
        else
93
        if(clr)         wp <= #1 2'h0;
94
        else
95
        if(we)          wp <= #1 wp_p1;
96
 
97
assign wp_p1 = wp + 2'h1;
98
assign wp_p2 = wp + 2'h2;
99
 
100
always @(posedge clk or negedge rst)
101
        if(!rst)        rp <= #1 2'h0;
102
        else
103
        if(clr)         rp <= #1 2'h0;
104
        else
105
        if(re)          rp <= #1 rp_p1;
106
 
107
assign rp_p1 = rp + 2'h1;
108
 
109
// Fifo Output
110
assign  dout = mem[ rp ];
111
 
112
// Fifo Input
113
always @(posedge clk)
114
        if(we)  mem[ wp ] <= #1 din;
115
 
116
// Status
117
assign empty = (wp == rp) & !gb;
118
assign full  = (wp == rp) &  gb;
119
 
120
// Guard Bit ...
121
always @(posedge clk)
122
        if(!rst)                        gb <= #1 1'b0;
123
        else
124
        if(clr)                         gb <= #1 1'b0;
125
        else
126
        if((wp_p1 == rp) & we)          gb <= #1 1'b1;
127
        else
128
        if(re)                          gb <= #1 1'b0;
129
 
130
endmodule
131
/////////////////////////////////////////////////////////////////////
132
////                                                             ////
133
////  OpenCores                    MC68HC11E based SPI interface ////
134
////                                                             ////
135
////  Author: Richard Herveille                                  ////
136
////          richard@asics.ws                                   ////
137
////          www.asics.ws                                       ////
138
////                                                             ////
139
/////////////////////////////////////////////////////////////////////
140
////                                                             ////
141
//// Copyright (C) 2002 Richard Herveille                        ////
142
////                    richard@asics.ws                         ////
143
////                                                             ////
144
//// This source file may be used and distributed without        ////
145
//// restriction provided that this copyright statement is not   ////
146
//// removed from the file and that any derivative work contains ////
147
//// the original copyright notice and the associated disclaimer.////
148
////                                                             ////
149
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
150
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
151
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
152
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
153
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
154
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
155
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
156
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
157
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
158
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
159
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
160
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
161
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
162
////                                                             ////
163
/////////////////////////////////////////////////////////////////////
164
 
165
//  CVS Log
166
//
167
//  $Id: simple_spi_top.v,v 1.2 2006/12/04 14:40:35 tame Exp $
168
//
169
//  $Date: 2006/12/04 14:40:35 $
170
//  $Revision: 1.2 $
171
//  $Author: tame $
172
//  $Locker:  $
173
//  $State: Exp $
174
//
175
// Change History:
176
//
177
//               Revision 1.7  2006/11/14 11:32:00  tame
178
//                               Removed Wishbone interface, added AMBA APB interface
179
//
180
//               Revision 1.6  2006/11/10 11:32:00  fwex
181
//                               Added SPISSN Register
182
//
183
//                               Revision 1.5  2004/02/28 15:59:50  rherveille
184
//               Fixed SCK_O generation bug.
185
//               This resulted in a major rewrite of the serial interface engine.
186
//
187
//               Revision 1.4  2003/08/01 11:41:54  rherveille
188
//               Fixed some timing bugs.
189
//
190
//               Revision 1.3  2003/01/09 16:47:59  rherveille
191
//               Updated clkcnt size and decoding due to new SPR bit assignments.
192
//
193
//               Revision 1.2  2003/01/07 13:29:52  rherveille
194
//               Changed SPR bits coding.
195
//
196
//               Revision 1.1.1.1  2002/12/22 16:07:15  rherveille
197
//               Initial release
198
//
199
//
200
//
201
// Motorola MC68HC11E based SPI interface
202
//
203
// Currently only MASTER mode is supported
204
//
205
 
206
// synopsys translate_off
207
//`include "timescale.v"
208
// synopsys translate_on
209
 
210
module simple_spi_top(/*AUTOARG*/
211
   // Outputs
212
   prdata_o, pirq_o, sck_o, mosi_o, ssn_o,
213
   // Inputs
214
   pclk_i, prst_i, psel_i, penable_i, paddr_i, pwrite_i, pwdata_i,
215
   miso_i
216
   );
217
 
218
   // 8-bit WISHBONE bus slave interface
219
   input         pclk_i;         // clock
220
   input         prst_i;         // reset (asynchronous active low)
221
   input         psel_i;         // cycle
222
   input         penable_i;      // strobe
223
   input [2:0]   paddr_i;        // address
224
   input         pwrite_i;       // write enable
225
   input [7:0]   pwdata_i;       // data input
226
 
227
   output [7:0]  prdata_o;       // data output
228
   reg [7:0]     prdata_o;
229
 
230
   output        pirq_o;         // interrupt output
231
   reg           pirq_o;
232
 
233
   // SPI port
234
   output        sck_o;          // serial clock output
235
   reg           sck_o;
236
 
237
   output        mosi_o;         // MasterOut SlaveIN
238
   input         miso_i;         // MasterIn SlaveOu
239
 
240
   // additional chip select output
241
   output [7:0]  ssn_o;  // Slave Select for the SPI Slaves
242
 
243
 
244
   //
245
   // Module body
246
   //
247
   reg [7:0] spcr;       // Serial Peripheral Control Register ('HC11 naming)
248
   wire [7:0] spsr;       // Serial Peripheral Status register ('HC11 naming)
249
   reg [7:0]  sper;       // Serial Peripheral Extension register
250
   reg [7:0]  treg; // Transmit register
251
   reg [7:0]  spssr;             // Serial Peripheral Chip Select Register
252
 
253
   // fifo signals
254
   wire [7:0] rfdout;
255
   reg        wfre, rfwe;
256
   wire       rfre, rffull, rfempty;
257
   wire [7:0] wfdout;
258
   wire       wfwe, wffull, wfempty;
259
 
260
   // misc signals
261
   wire       tirq;     // transfer interrupt (selected number of transfers done)
262
   wire       wfov;     // write fifo overrun (writing while fifo full)
263
   reg [1:0]  state;    // statemachine state
264
   reg [2:0]  bcnt;
265
 
266
   wire       apb_acc = psel_i & penable_i;
267
   wire       apb_wr = psel_i & penable_i & pwrite_i;
268
 
269
   // added acknowledge register to be compatible with
270
   // Wishbone modeling (controls write and read fifo enables)
271
   reg        ack;
272
 
273
   // route the Chip Select Register to the port
274
   assign     ssn_o = spssr;
275
 
276
   // write registers
277
   always @(posedge pclk_i or negedge prst_i)
278
     if (~prst_i)
279
       begin
280
          spcr <= #1 8'h10;  // set master bit
281
          sper <= #1 8'h00;
282
                  spssr <= #1 8'hFF;
283
       end
284
     else
285
       if (apb_wr) begin
286
          if (paddr_i == 3'b000)
287
            spcr <= #1 pwdata_i | 8'h10; // always set master bit
288
          else if (paddr_i == 3'b011)
289
            sper <= #1 pwdata_i;
290
                  else if (paddr_i == 3'b100)
291
                    spssr <= #1 pwdata_i;
292
       end
293
 
294
   // write fifo
295
   assign wfwe = apb_acc & (paddr_i == 3'b010) & pwrite_i;
296
   assign wfov = wfwe & wffull;
297
 
298
   // data output
299
   always @(posedge pclk_i)
300
     case(paddr_i) // synopsys full_case parallel_case
301
       3'b000: prdata_o <= #1 spcr;
302
       3'b001: prdata_o <= #1 spsr;
303
       3'b010: prdata_o <= #1 rfdout;
304
       3'b011: prdata_o <= #1 sper;
305
           3'b100: prdata_o <= #1 spssr;
306
           default: prdata_o <= #1 8'bX;
307
     endcase
308
 
309
   // read fifo
310
   assign rfre = apb_acc & (paddr_i == 3'b010) & ~pwrite_i;
311
 
312
   // model acknowlegde for compatibility with original test bench
313
   always @(posedge pclk_i or negedge prst_i)
314
     if (~prst_i)
315
       ack <= #1 1'b0;
316
     else
317
       ack <= #1 apb_acc & ~ack;
318
 
319
   // decode Serial Peripheral Control Register
320
   wire   spie = spcr[7];   // Interrupt enable bit
321
   wire   spe  = spcr[6];   // System Enable bit
322
   wire   dwom = spcr[5];   // Port D Wired-OR Mode Bit
323
   wire   mstr = spcr[4];   // Master Mode Select Bit
324
   wire   cpol = spcr[3];   // Clock Polarity Bit
325
   wire   cpha = spcr[2];   // Clock Phase Bit
326
   wire [1:0] spr  = spcr[1:0]; // Clock Rate Select Bits
327
 
328
   // decode Serial Peripheral Extension Register
329
   wire [1:0] icnt = sper[7:6]; // interrupt on transfer count
330
   wire [1:0] spre = sper[1:0]; // extended clock rate select
331
 
332
   wire [3:0] espr = {spre, spr};
333
 
334
   // generate status register
335
   wire       wr_spsr = apb_wr & (paddr_i == 3'b001);
336
 
337
   reg        spif;
338
   always @(posedge pclk_i)
339
     if (~spe)
340
       spif <= #1 1'b0;
341
     else
342
       spif <= #1 (tirq | spif) & ~(wr_spsr & pwdata_i[7]);
343
 
344
   reg        wcol;
345
   always @(posedge pclk_i)
346
     if (~spe)
347
       wcol <= #1 1'b0;
348
     else
349
       wcol <= #1 (wfov | wcol) & ~(wr_spsr & pwdata_i[6]);
350
 
351
   assign     spsr[7]   = spif;
352
   assign     spsr[6]   = wcol;
353
   assign     spsr[5:4] = 2'b00;
354
   assign     spsr[3]   = wffull;
355
   assign     spsr[2]   = wfempty;
356
   assign     spsr[1]   = rffull;
357
   assign     spsr[0]   = rfempty;
358
 
359
 
360
   // generate IRQ output (pirq_o)
361
   always @(posedge pclk_i)
362
     pirq_o <= #1 spif & spie;
363
 
364
   //
365
   // hookup read/write buffer fifo
366
   fifo4 #(8) rfifo
367
     (.clk   ( pclk_i   ),
368
          .rst   ( prst_i   ),
369
          .clr   ( ~spe    ),
370
          .din   ( treg    ),
371
          .we    ( rfwe    ),
372
          .dout  ( rfdout  ),
373
          .re    ( rfre    ),
374
          .full  ( rffull  ),
375
          .empty ( rfempty )
376
      );
377
 
378
   fifo4 #(8) wfifo
379
     (.clk   ( pclk_i   ),
380
          .rst   ( prst_i   ),
381
          .clr   ( ~spe    ),
382
          .din   ( pwdata_i   ),
383
          .we    ( wfwe    ),
384
          .dout  ( wfdout  ),
385
          .re    ( wfre    ),
386
          .full  ( wffull  ),
387
          .empty ( wfempty )
388
      );
389
 
390
   //
391
   // generate clk divider
392
   reg [11:0] clkcnt;
393
   always @(posedge pclk_i)
394
     if(spe & (|clkcnt & |state))
395
       clkcnt <= #1 clkcnt - 10'h1;
396
     else
397
       case (espr) // synopsys full_case parallel_case
398
         4'b0000: clkcnt <= #1 12'h0;   // 2   -- original M68HC11 coding
399
         4'b0001: clkcnt <= #1 12'h1;   // 4   -- original M68HC11 coding
400
         4'b0010: clkcnt <= #1 12'h3;   // 8   -- original M68HC11 coding
401
         4'b0011: clkcnt <= #1 12'hf;   // 32  -- original M68HC11 coding
402
         4'b0100: clkcnt <= #1 12'h1f;  // 64
403
         4'b0101: clkcnt <= #1 12'h7;   // 16
404
         4'b0110: clkcnt <= #1 12'h3f;  // 128
405
         4'b0111: clkcnt <= #1 12'h7f;  // 256
406
         4'b1000: clkcnt <= #1 12'hff;  // 512
407
         4'b1001: clkcnt <= #1 12'h1ff; // 1024
408
         4'b1010: clkcnt <= #1 12'h3ff; // 2048
409
         4'b1011: clkcnt <= #1 12'h7ff; // 4096
410
       endcase
411
 
412
   // generate clock enable signal
413
   wire       ena = ~|clkcnt;
414
 
415
   // transfer statemachine
416
   always @(posedge pclk_i)
417
     if (~spe)
418
       begin
419
          state <= #1 2'b00; // idle
420
          bcnt  <= #1 3'h0;
421
          treg  <= #1 8'h00;
422
          wfre  <= #1 1'b0;
423
          rfwe  <= #1 1'b0;
424
          sck_o <= #1 1'b0;
425
       end
426
     else
427
       begin
428
          wfre <= #1 1'b0;
429
          rfwe <= #1 1'b0;
430
 
431
          case (state) //synopsys full_case parallel_case
432
            2'b00: // idle state
433
              begin
434
                 bcnt  <= #1 3'h7;   // set transfer counter
435
                 treg  <= #1 wfdout; // load transfer register
436
                 sck_o <= #1 cpol;   // set sck
437
 
438
                 if (~wfempty) begin
439
                    wfre  <= #1 1'b1;
440
                    state <= #1 2'b01;
441
                    if (cpha) sck_o <= #1 ~sck_o;
442
                 end
443
              end
444
 
445
            2'b01: // clock-phase2, next data
446
              if (ena) begin
447
                 sck_o   <= #1 ~sck_o;
448
                 state   <= #1 2'b11;
449
              end
450
 
451
            2'b11: // clock phase1
452
              if (ena) begin
453
                 treg <= #1 {treg[6:0], miso_i};
454
                 bcnt <= #1 bcnt -3'h1;
455
 
456
                 if (~|bcnt) begin
457
                    state <= #1 2'b00;
458
                    sck_o <= #1 cpol;
459
                    rfwe  <= #1 1'b1;
460
                 end else begin
461
                    state <= #1 2'b01;
462
                    sck_o <= #1 ~sck_o;
463
                 end
464
              end
465
 
466
            2'b10: state <= #1 2'b00;
467
          endcase
468
       end
469
 
470
   assign mosi_o = treg[7];
471
 
472
 
473
   // count number of transfers (for interrupt generation)
474
   reg [1:0] tcnt; // transfer count
475
   always @(posedge pclk_i)
476
     if (~spe)
477
       tcnt <= #1 icnt;
478
     else if (rfwe) // rfwe gets asserted when all bits have been transfered
479
       if (|tcnt)
480
         tcnt <= #1 tcnt - 2'h1;
481
       else
482
         tcnt <= #1 icnt;
483
 
484
   assign    tirq = ~|tcnt & rfwe;
485
 
486
endmodule
487
 

powered by: WebSVN 2.1.0

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