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

Subversion Repositories oms8051mini

[/] [oms8051mini/] [trunk/] [rtl/] [spi/] [spi_ctl.v] - Blame information for rev 2

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

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

powered by: WebSVN 2.1.0

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