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

Subversion Repositories tiny_spi

[/] [tiny_spi/] [trunk/] [sopc/] [hdl/] [tiny_spi.v] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 hippo5329
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  tiny_spi.v                                                  ////
4
////                                                              ////
5
////  This file is part of the TINY SPI IP core project           ////
6
////  http://www.opencores.org/projects/tiny_spi/                 ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - Thomas Chou <thomas@wytron.com.tw>                    ////
10
////                                                              ////
11
////  All additional information is avaliable in the README       ////
12
////  file.                                                       ////
13
////                                                              ////
14
//////////////////////////////////////////////////////////////////////
15
////                                                              ////
16
//// Copyright (C) 2010 Authors                                   ////
17
////                                                              ////
18
//// This source file may be used and distributed without         ////
19
//// restriction provided that this copyright statement is not    ////
20
//// removed from the file and that any derivative work contains  ////
21
//// the original copyright notice and the associated disclaimer. ////
22
////                                                              ////
23
//// This source file is free software; you can redistribute it   ////
24
//// and/or modify it under the terms of the GNU Lesser General   ////
25
//// Public License as published by the Free Software Foundation; ////
26
//// either version 2.1 of the License, or (at your option) any   ////
27
//// later version.                                               ////
28
////                                                              ////
29
//// This source is distributed in the hope that it will be       ////
30
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
31
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
32
//// PURPOSE.  See the GNU Lesser General Public License for more ////
33
//// details.                                                     ////
34
////                                                              ////
35
//// You should have received a copy of the GNU Lesser General    ////
36
//// Public License along with this source; if not, download it   ////
37
//// from http://www.opencores.org/lgpl.shtml                     ////
38
////                                                              ////
39
//////////////////////////////////////////////////////////////////////
40
 
41
module tiny_spi(
42
   // system
43
   input          rst_i,
44
   input          clk_i,
45
   // memory mapped
46
   input          stb_i,
47
   input          we_i,
48
   output [31:0]  dat_o,
49
   input [31:0]   dat_i,
50
   output         int_o,
51
   input [2:0]     adr_i,
52
   // input       cyc_i, // comment out for avalon
53
   // output      ack_o, // comment out for avalon
54
 
55
   // spi
56
   output         MOSI,
57
   output         SCLK,
58
   input          MISO
59
   );
60
 
61
   parameter BAUD_WIDTH = 8;
62
   parameter BAUD_DIV = 0;
63
   parameter SPI_MODE = 0;
64
   parameter BC_WIDTH = 3;
65
   parameter DIV_WIDTH = BAUD_DIV ? $clog2(BAUD_DIV / 2 - 1) : BAUD_WIDTH;
66
 
67
 
68
   reg [7:0]       sr8, bb8;
69
   wire [7:0]      sr8_sf;
70
   reg [BC_WIDTH - 1:0]          bc, bc_next;
71
   reg [DIV_WIDTH - 1:0] ccr;
72
   reg [DIV_WIDTH - 1:0] cc, cc_next;
73
   wire           misod;
74
   wire           cstb, wstb, bstb, istb;
75
   reg            sck;
76
   reg            sf, ld;
77
   reg            bba;   // buffer flag
78
   reg            txren, txeen;
79
   wire           txr, txe;
80
   wire           cpol, cpha;
81
   reg            cpolr, cphar;
82
   wire           wr;
83
   wire           cyc_i; // comment out for wishbone
84
   wire           ack_o; // comment out for wishbone
85
   assign cyc_i = 1'b1;  // comment out for wishbone
86
   assign ack_o = stb_i & cyc_i; // zero wait
87
   assign wr = stb_i & cyc_i & we_i & ack_o;
88
   assign wstb = wr & (adr_i == 1);
89
   assign istb = wr & (adr_i == 2);
90
   assign cstb = wr & (adr_i == 3);
91
   assign bstb = wr & (adr_i == 4);
92
   assign sr8_sf = { sr8[6:0],misod };
93
   assign dat_o =
94
                      (sr8 & {8{(adr_i == 0)}})
95
                    | (bb8 & {8{(adr_i == 1)}})
96
                    | ({ txr, txe } & {8{(adr_i == 2)}})
97
                      ;
98
 
99
   parameter
100
     IDLE = 0,
101
     PHASE1 = 1,
102
     PHASE2 = 2
103
     ;
104
 
105
   reg [1:0] spi_seq, spi_seq_next;
106
   always @(posedge clk_i or posedge rst_i)
107
     if (rst_i)
108
       spi_seq <= IDLE;
109
     else
110
       spi_seq <= spi_seq_next;
111
 
112
   always @(posedge clk_i)
113
     begin
114
        cc <= cc_next;
115
        bc <= bc_next;
116
     end
117
 
118
   always @(/*AS*/bba or bc or cc or ccr or cpha or cpol or spi_seq)
119
     begin
120
        sck = cpol;
121
        cc_next = BAUD_DIV ? (BAUD_DIV / 2 - 1) : ccr;
122
        bc_next = bc;
123
        ld = 1'b0;
124
        sf = 1'b0;
125
 
126
        case (spi_seq)
127
          IDLE:
128
            begin
129
               if (bba)
130
                 begin
131
                    bc_next = 7;
132
                    ld = 1'b1;
133
                    spi_seq_next = PHASE2;
134
                 end
135
               else
136
                 spi_seq_next = IDLE;
137
            end
138
          PHASE2:
139
            begin
140
               sck = (cpol ^ cpha);
141
               if (cc == 0)
142
                 spi_seq_next = PHASE1;
143
               else
144
                 begin
145
                    cc_next = cc - 1;
146
                    spi_seq_next = PHASE2;
147
                 end
148
            end
149
          PHASE1:
150
            begin
151
               sck = ~(cpol ^ cpha);
152
               if (cc == 0)
153
                 begin
154
                    bc_next = bc -1;
155
                    sf = 1'b1;
156
                    if (bc == 0)
157
                      begin
158
                         if (bba)
159
                           begin
160
                              bc_next = 7;
161
                              ld = 1'b1;
162
                              spi_seq_next = PHASE2;
163
                           end
164
                         else
165
                           spi_seq_next = IDLE;
166
                      end
167
                    else
168
                      spi_seq_next = PHASE2;
169
                 end
170
               else
171
                 begin
172
                    cc_next = cc - 1;
173
                    spi_seq_next = PHASE1;
174
                 end
175
            end
176
        endcase
177
     end // always @ (...
178
 
179
   always @(posedge clk_i)
180
     begin
181
        if (cstb) // control reg
182
          { cpolr, cphar } <= dat_i;
183
        else
184
          { cpolr, cphar } <= { cpolr, cphar };
185
 
186
        if (istb) // irq enable reg
187
          { txren, txeen } <= dat_i;
188
        else
189
          { txren, txeen } <= { txren, txeen };
190
 
191
        if (bstb) // baud reg
192
          ccr <= dat_i;
193
        else
194
          ccr <= ccr;
195
 
196
        if (ld)   // shift reg
197
          sr8 <= bb8;
198
        else if (sf)
199
          sr8 <= sr8_sf;
200
        else
201
          sr8 <= sr8;
202
 
203
        if (wstb) // buffer reg
204
          bb8 <= dat_i;
205
        else if (ld)
206
          bb8 <= (spi_seq == IDLE) ? sr8 : sr8_sf;
207
        else
208
          bb8 <= bb8;
209
     end // always @ (posedge clk_i)
210
 
211
   always @(posedge clk_i or posedge rst_i)
212
     begin
213
        if (rst_i)
214
          bba <= 1'b0;
215
        else if (wstb)
216
          bba <= 1'b1;
217
        else if (ld)
218
          bba <= 1'b0;
219
        else
220
          bba <= bba;
221
     end
222
 
223
   assign { cpol, cpha } = ((SPI_MODE >= 0) & (SPI_MODE < 4)) ?
224
                           SPI_MODE : { cpolr, cphar };
225
   assign txe = (spi_seq == IDLE);
226
   assign txr = ~bba;
227
   assign int_o = (txr & txren) | (txe & txeen);
228
   assign SCLK = sck;
229
   assign MOSI = sr8[7];
230
   assign misod = MISO;
231
 
232
endmodule

powered by: WebSVN 2.1.0

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