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

Subversion Repositories turbo8051

[/] [turbo8051/] [trunk/] [rtl/] [spi/] [spi_ctl.v] - Blame information for rev 23

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

Line No. Rev Author Line
1 7 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  Tubo 8051 cores SPI Interface Module                        ////
4
////                                                              ////
5
////  This file is part of the Turbo 8051 cores project           ////
6
////  http://www.opencores.org/cores/turbo8051/                   ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  Turbo 8051 definitions.                                     ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////    nothing                                                   ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Dinesh Annayya, dinesha@opencores.org                 ////
16
////                                                              ////
17
//////////////////////////////////////////////////////////////////////
18
////                                                              ////
19
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
20
////                                                              ////
21
//// This source file may be used and distributed without         ////
22
//// restriction provided that this copyright statement is not    ////
23
//// removed from the file and that any derivative work contains  ////
24
//// the original copyright notice and the associated disclaimer. ////
25
////                                                              ////
26
//// This source file is free software; you can redistribute it   ////
27
//// and/or modify it under the terms of the GNU Lesser General   ////
28
//// Public License as published by the Free Software Foundation; ////
29
//// either version 2.1 of the License, or (at your option) any   ////
30
//// later version.                                               ////
31
////                                                              ////
32
//// This source is distributed in the hope that it will be       ////
33
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
34
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
35
//// PURPOSE.  See the GNU Lesser General Public License for more ////
36
//// details.                                                     ////
37
////                                                              ////
38
//// You should have received a copy of the GNU Lesser General    ////
39
//// Public License along with this source; if not, download it   ////
40
//// from http://www.opencores.org/lgpl.shtml                     ////
41
////                                                              ////
42
//////////////////////////////////////////////////////////////////////
43
 
44
 
45
 
46
module spi_ctl
47
       ( clk,
48
         reset_n,
49
         sck_int,
50
 
51
 
52
         cfg_op_req,
53
         cfg_op_type,
54
         cfg_transfer_size,
55
         cfg_sck_period,
56
         cfg_sck_cs_period,
57
         cfg_cs_byte,
58
         cfg_datain,
59
         cfg_dataout,
60
         op_done,
61
 
62
         cs_int_n,
63
         sck_pe,
64
         sck_ne,
65
         shift_out,
66
         shift_in,
67
         byte_out,
68
         byte_in,
69
         load_byte
70
 
71
         );
72
 
73
 //*************************************************************************
74
 
75
  input          clk, reset_n;
76
  input          cfg_op_req;
77
  input [1:0]    cfg_op_type;
78
  input [1:0]    cfg_transfer_size;
79
 
80
  input [5:0]    cfg_sck_period;
81
  input [4:0]    cfg_sck_cs_period; // cs setup & hold period
82
  input [7:0]    cfg_cs_byte;
83
  input [31:0]   cfg_datain;
84
  output [31:0]  cfg_dataout;
85
 
86
  output [7:0]    byte_out; // Byte out for Serial Shifting out
87
  input  [7:0]    byte_in;  // Serial Received Byte
88
  output          sck_int;
89
  output          cs_int_n;
90
  output          sck_pe;
91
  output          sck_ne;
92
  output          shift_out;
93
  output          shift_in;
94
  output          load_byte;
95
  output          op_done;
96
 
97
  reg    [31:0]   cfg_dataout;
98
  reg             sck_ne;
99
  reg             sck_pe;
100
  reg             sck_int;
101
  reg [5:0]       clk_cnt;
102
  reg [5:0]       sck_cnt;
103
 
104
  reg [3:0]       spiif_cs;
105
  reg             shift_enb;
106
  reg             cs_int_n;
107
  reg             clr_sck_cnt ;
108
  reg             sck_out_en;
109
 
110
  wire [5:0]      sck_half_period;
111
  reg             load_byte;
112
  reg             shift_in;
113
  reg             op_done;
114
  reg [2:0]       byte_cnt;
115
 
116
 
117
  `define SPI_IDLE   4'b0000
118
  `define SPI_CS_SU  4'b0001
119
  `define SPI_WRITE  4'b0010
120
  `define SPI_READ   4'b0011
121
  `define SPI_CS_HLD 4'b0100
122
  `define SPI_WAIT   4'b0101
123
 
124
 
125
  assign sck_half_period = {1'b0, cfg_sck_period[5:1]};
126
  // The first transition on the sck_toggle happens one SCK period
127
  // after op_en or boot_en is asserted
128
  always @(posedge clk or negedge reset_n) begin
129
     if(!reset_n) begin
130
        sck_ne   <= 1'b0;
131
        clk_cnt  <= 6'h1;
132
        sck_pe   <= 1'b0;
133
        sck_int  <= 1'b0;
134
     end // if (!reset_n)
135
     else
136
     begin
137
        if(cfg_op_req)
138
        begin
139
           if(clk_cnt == sck_half_period)
140
           begin
141
              sck_ne <= 1'b1;
142
              sck_pe <= 1'b0;
143
              if(sck_out_en) sck_int <= 0;
144
              clk_cnt <= clk_cnt + 1'b1;
145
           end // if (clk_cnt == sck_half_period)
146
           else
147
           begin
148
              if(clk_cnt == cfg_sck_period)
149
              begin
150
                 sck_ne <= 1'b0;
151
                 sck_pe <= 1'b1;
152
                 if(sck_out_en) sck_int <= 1;
153
                 clk_cnt <= 6'h1;
154
              end // if (clk_cnt == cfg_sck_period)
155
              else
156
              begin
157
                 clk_cnt <= clk_cnt + 1'b1;
158
                 sck_pe <= 1'b0;
159
                 sck_ne <= 1'b0;
160
              end // else: !if(clk_cnt == cfg_sck_period)
161
           end // else: !if(clk_cnt == sck_half_period)
162
        end // if (op_en)
163
        else
164
        begin
165
           clk_cnt    <= 6'h1;
166
           sck_pe     <= 1'b0;
167
           sck_ne     <= 1'b0;
168
        end // else: !if(op_en)
169
     end // else: !if(!reset_n)
170
  end // always @ (posedge clk or negedge reset_n)
171
 
172
 
173
wire [1:0] cs_data =  (byte_cnt == 2'b00) ? cfg_cs_byte[7:6]  :
174
                      (byte_cnt == 2'b01) ? cfg_cs_byte[5:4]  :
175
                      (byte_cnt == 2'b10) ? cfg_cs_byte[3:2]  : cfg_cs_byte[1:0] ;
176
 
177
wire [7:0] byte_out = (byte_cnt == 2'b00) ? cfg_datain[31:24] :
178
                      (byte_cnt == 2'b01) ? cfg_datain[23:16] :
179
                      (byte_cnt == 2'b10) ? cfg_datain[15:8]  : cfg_datain[7:0] ;
180
 
181
assign shift_out =  shift_enb && sck_ne;
182
 
183
always @(posedge clk or negedge reset_n) begin
184
   if(!reset_n) begin
185
      spiif_cs    <= `SPI_IDLE;
186
      sck_cnt     <= 6'h0;
187
      shift_in    <= 1'b0;
188
      clr_sck_cnt <= 1'b1;
189
      byte_cnt    <= 2'b00;
190
      cs_int_n    <= 1'b1;
191
      sck_out_en  <= 1'b0;
192
      shift_enb   <= 1'b0;
193
      cfg_dataout <= 32'h0;
194
      load_byte   <= 1'b0;
195
   end
196
   else begin
197
      if(sck_ne)
198
         sck_cnt <=  clr_sck_cnt  ? 6'h0 : sck_cnt + 1 ;
199
 
200
      case(spiif_cs)
201
      `SPI_IDLE   :
202
      begin
203
          op_done     <= 0;
204
          clr_sck_cnt <= 1'b1;
205
          sck_out_en  <= 1'b0;
206
          shift_enb   <= 1'b0;
207
          if(cfg_op_req)
208
          begin
209
              cfg_dataout <= 32'h0;
210
              spiif_cs    <= `SPI_CS_SU;
211
           end
212
           else begin
213
              spiif_cs <= `SPI_IDLE;
214
           end
215
      end
216
 
217
      `SPI_CS_SU  :
218
       begin
219
          if(sck_ne) begin
220
            cs_int_n <= cs_data[1];
221
            if(sck_cnt == cfg_sck_cs_period) begin
222
               clr_sck_cnt <= 1'b1;
223
               if(cfg_op_type == 0) begin // Write Mode
224
                  load_byte   <= 1'b1;
225
                  spiif_cs    <= `SPI_WRITE;
226
                  shift_enb   <= 1'b0;
227
               end else begin
228
                  shift_in    <= 1;
229
                  spiif_cs    <= `SPI_READ;
230
                end
231
             end
232
             else begin
233
                clr_sck_cnt <= 1'b0;
234
             end
235
         end
236
      end
237
 
238
      `SPI_WRITE :
239
       begin
240
         load_byte   <= 1'b0;
241
         if(sck_ne) begin
242
           if(sck_cnt == 3'h7 )begin
243
              clr_sck_cnt <= 1'b1;
244
              spiif_cs    <= `SPI_CS_HLD;
245
              shift_enb   <= 1'b0;
246
              sck_out_en  <= 1'b0; // Disable clock output
247
           end
248
           else begin
249
              shift_enb   <= 1'b1;
250
              sck_out_en  <= 1'b1;
251
              clr_sck_cnt <= 1'b0;
252
           end
253
         end else begin
254
            shift_enb   <= 1'b1;
255
         end
256
      end
257
 
258
      `SPI_READ :
259
       begin
260
         if(sck_ne) begin
261
             if( sck_cnt == 3'h7 ) begin
262
                clr_sck_cnt <= 1'b1;
263
                shift_in    <= 0;
264
                spiif_cs    <= `SPI_CS_HLD;
265
                sck_out_en  <= 1'b0; // Disable clock output
266
             end
267
             else begin
268
                sck_out_en  <= 1'b1; // Disable clock output
269
                clr_sck_cnt <= 1'b0;
270
             end
271
         end
272
      end
273
 
274
      `SPI_CS_HLD : begin
275
         if(sck_ne) begin
276
             cs_int_n = cs_data[0];
277
            if(sck_cnt == cfg_sck_cs_period) begin
278
               if(cfg_op_type == 1) begin // Read Mode
279
                  cfg_dataout <= (byte_cnt[1:0] == 2'b00) ? { byte_in, cfg_dataout[23:0] } :
280
                                 (byte_cnt[1:0] == 2'b01) ? { cfg_dataout[31:24] ,
281
                                                              byte_in, cfg_dataout[15:0] } :
282
                                 (byte_cnt[1:0] == 2'b10) ? { cfg_dataout[31:16] ,
283
                                                              byte_in, cfg_dataout[7:0]  } :
284
                                                            { cfg_dataout[31:8]  ,
285
                                                              byte_in  } ;
286
               end
287
               clr_sck_cnt <= 1'b1;
288
               if(byte_cnt == cfg_transfer_size) begin
289
                  spiif_cs <= `SPI_WAIT;
290
                  byte_cnt <= 0;
291
                  op_done  <= 1;
292
               end else begin
293
                  byte_cnt <= byte_cnt +1;
294
                  spiif_cs <= `SPI_CS_SU;
295
               end
296
            end
297
            else begin
298
                clr_sck_cnt <= 1'b0;
299
            end
300
         end
301
      end // case: `SPI_CS_HLD    
302
      `SPI_WAIT : begin
303
          if(!cfg_op_req) // Wait for Request de-assertion
304
             spiif_cs <= `SPI_IDLE;
305
       end
306
    endcase // casex(spiif_cs)
307
   end
308
end // always @(sck_ne
309
 
310
endmodule

powered by: WebSVN 2.1.0

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