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

Subversion Repositories oms8051mini

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

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

powered by: WebSVN 2.1.0

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