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

Subversion Repositories spi

[/] [spi/] [tags/] [asyst_3/] [rtl/] [verilog/] [spi_shift.v] - Blame information for rev 21

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

Line No. Rev Author Line
1 2 simons
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  spi_shift.v                                                 ////
4
////                                                              ////
5
////  This file is part of the SPI IP core project                ////
6
////  http://www.opencores.org/projects/spi/                      ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - Simon Srot (simons@opencores.org)                     ////
10
////                                                              ////
11
////  All additional information is avaliable in the Readme.txt   ////
12
////  file.                                                       ////
13
////                                                              ////
14
//////////////////////////////////////////////////////////////////////
15
////                                                              ////
16
//// Copyright (C) 2002 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
`include "spi_defines.v"
42
`include "timescale.v"
43
 
44 13 simons
module spi_shift (clk, rst, latch, byte_sel, len, lsb, go,
45 2 simons
                  pos_edge, neg_edge, rx_negedge, tx_negedge,
46
                  tip, last,
47
                  p_in, p_out, s_clk, s_in, s_out);
48
 
49
  parameter Tp = 1;
50
 
51
  input                          clk;          // system clock
52
  input                          rst;          // reset
53 9 simons
  input                    [3:0] latch;        // latch signal for storing the data in shift register
54 13 simons
  input                    [3:0] byte_sel;     // byte select signals for storing the data in shift register
55 2 simons
  input [`SPI_CHAR_LEN_BITS-1:0] len;          // data len in bits (minus one)
56
  input                          lsb;          // lbs first on the line
57
  input                          go;           // start stansfer
58
  input                          pos_edge;     // recognize posedge of sclk
59
  input                          neg_edge;     // recognize negedge of sclk
60
  input                          rx_negedge;   // s_in is sampled on negative edge 
61
  input                          tx_negedge;   // s_out is driven on negative edge
62
  output                         tip;          // transfer in progress
63
  output                         last;         // last bit
64 7 simons
  input                   [31:0] p_in;         // parallel in
65 2 simons
  output     [`SPI_MAX_CHAR-1:0] p_out;        // parallel out
66
  input                          s_clk;        // serial clock
67
  input                          s_in;         // serial in
68
  output                         s_out;        // serial out
69
 
70
  reg                            s_out;
71
  reg                            tip;
72
 
73
  reg     [`SPI_CHAR_LEN_BITS:0] cnt;          // data bit count
74
  reg        [`SPI_MAX_CHAR-1:0] data;         // shift register
75
  wire    [`SPI_CHAR_LEN_BITS:0] tx_bit_pos;   // next bit position
76
  wire    [`SPI_CHAR_LEN_BITS:0] rx_bit_pos;   // next bit position
77
  wire                           rx_clk;       // rx clock enable
78
  wire                           tx_clk;       // tx clock enable
79
 
80
  assign p_out = data;
81
 
82
  assign tx_bit_pos = lsb ? {!(|len), len} - cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1};
83
  assign rx_bit_pos = lsb ? {!(|len), len} - (rx_negedge ? cnt + {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1} : cnt) :
84
                            (rx_negedge ? cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1});
85
 
86
  assign last = !(|cnt);
87
 
88
  assign rx_clk = (rx_negedge ? neg_edge : pos_edge) && (!last || s_clk);
89
  assign tx_clk = (tx_negedge ? neg_edge : pos_edge) && !last;
90
 
91
  // Character bit counter
92
  always @(posedge clk or posedge rst)
93
  begin
94
    if(rst)
95
      cnt <= #Tp {`SPI_CHAR_LEN_BITS+1{1'b0}};
96
    else
97
      begin
98
        if(tip)
99
          cnt <= #Tp pos_edge ? (cnt - {{`SPI_CHAR_LEN_BITS{1'b0}}, 1'b1}) : cnt;
100
        else
101
          cnt <= #Tp !(|len) ? {1'b1, {`SPI_CHAR_LEN_BITS{1'b0}}} : {1'b0, len};
102
      end
103
  end
104
 
105
  // Transfer in progress
106
  always @(posedge clk or posedge rst)
107
  begin
108
    if(rst)
109
      tip <= #Tp 1'b0;
110
  else if(go && ~tip)
111
    tip <= #Tp 1'b1;
112
  else if(tip && last && pos_edge)
113
    tip <= #Tp 1'b0;
114
  end
115
 
116
  // Sending bits to the line
117
  always @(posedge clk or posedge rst)
118
  begin
119
    if (rst)
120
      s_out   <= #Tp 1'b0;
121
    else
122
      s_out <= #Tp (tx_clk || !tip) ? data[tx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] : s_out;
123
  end
124
 
125
  // Receiving bits from the line
126
  always @(posedge clk or posedge rst)
127
  begin
128
    if (rst)
129
      data   <= #Tp {`SPI_MAX_CHAR{1'b0}};
130 9 simons
`ifdef SPI_MAX_CHAR_128
131
    else if (latch[0] && !tip)
132 13 simons
      begin
133 21 simons
        if (byte_sel[3])
134 13 simons
          data[31:24] <= #Tp p_in[31:24];
135 21 simons
        if (byte_sel[2])
136
          data[23:16] <= #Tp p_in[23:16];
137 13 simons
        if (byte_sel[1])
138
          data[15:8] <= #Tp p_in[15:8];
139 21 simons
        if (byte_sel[0])
140 13 simons
          data[7:0] <= #Tp p_in[7:0];
141
      end
142 9 simons
    else if (latch[1] && !tip)
143 13 simons
      begin
144 21 simons
        if (byte_sel[3])
145 13 simons
          data[63:56] <= #Tp p_in[31:24];
146 21 simons
        if (byte_sel[2])
147
          data[55:48] <= #Tp p_in[23:16];
148 13 simons
        if (byte_sel[1])
149
          data[47:40] <= #Tp p_in[15:8];
150 21 simons
        if (byte_sel[0])
151 13 simons
          data[39:32] <= #Tp p_in[7:0];
152
      end
153 9 simons
    else if (latch[2] && !tip)
154 13 simons
      begin
155 21 simons
        if (byte_sel[3])
156 13 simons
          data[95:88] <= #Tp p_in[31:24];
157 21 simons
        if (byte_sel[2])
158
          data[87:80] <= #Tp p_in[23:16];
159 13 simons
        if (byte_sel[1])
160
          data[79:72] <= #Tp p_in[15:8];
161 21 simons
        if (byte_sel[0])
162 13 simons
          data[71:64] <= #Tp p_in[7:0];
163
      end
164
    else if (latch[3] && !tip)
165
      begin
166 21 simons
        if (byte_sel[3])
167 13 simons
          data[127:120] <= #Tp p_in[31:24];
168 21 simons
        if (byte_sel[2])
169
          data[119:112] <= #Tp p_in[23:16];
170 13 simons
        if (byte_sel[1])
171
          data[111:104] <= #Tp p_in[15:8];
172 21 simons
        if (byte_sel[0])
173 13 simons
          data[103:96] <= #Tp p_in[7:0];
174
      end
175 9 simons
`else
176 7 simons
`ifdef SPI_MAX_CHAR_64
177 9 simons
    else if (latch[0] && !tip)
178 13 simons
      begin
179 21 simons
        if (byte_sel[3])
180 13 simons
          data[31:24] <= #Tp p_in[31:24];
181 21 simons
        if (byte_sel[2])
182
          data[23:16] <= #Tp p_in[23:16];
183 13 simons
        if (byte_sel[1])
184
          data[15:8] <= #Tp p_in[15:8];
185 21 simons
        if (byte_sel[0])
186 13 simons
          data[7:0] <= #Tp p_in[7:0];
187
      end
188 9 simons
    else if (latch[1] && !tip)
189 13 simons
      begin
190 21 simons
        if (byte_sel[3])
191 13 simons
          data[63:56] <= #Tp p_in[31:24];
192 21 simons
        if (byte_sel[2])
193
          data[55:48] <= #Tp p_in[23:16];
194 13 simons
        if (byte_sel[1])
195
          data[47:40] <= #Tp p_in[15:8];
196 21 simons
        if (byte_sel[0])
197 13 simons
          data[39:32] <= #Tp p_in[7:0];
198
      end
199 7 simons
`else
200 9 simons
    else if (latch[0] && !tip)
201 13 simons
      begin
202 19 simons
      `ifdef SPI_MAX_CHAR_8
203 21 simons
        if (byte_sel[0])
204 13 simons
          data[`SPI_MAX_CHAR-1:0] <= #Tp p_in[`SPI_MAX_CHAR-1:0];
205
      `endif
206 19 simons
      `ifdef SPI_MAX_CHAR_16
207 21 simons
        if (byte_sel[0])
208 13 simons
          data[7:0] <= #Tp p_in[7:0];
209 21 simons
        if (byte_sel[1])
210 15 simons
          data[`SPI_MAX_CHAR-1:8] <= #Tp p_in[`SPI_MAX_CHAR-1:8];
211
      `endif
212 19 simons
      `ifdef SPI_MAX_CHAR_24
213 21 simons
        if (byte_sel[0])
214 15 simons
          data[7:0] <= #Tp p_in[7:0];
215 21 simons
        if (byte_sel[1])
216
          data[15:8] <= #Tp p_in[15:8];
217 15 simons
        if (byte_sel[2])
218
          data[`SPI_MAX_CHAR-1:16] <= #Tp p_in[`SPI_MAX_CHAR-1:16];
219 13 simons
      `endif
220 19 simons
      `ifdef SPI_MAX_CHAR_32
221 21 simons
        if (byte_sel[0])
222 13 simons
          data[7:0] <= #Tp p_in[7:0];
223 21 simons
        if (byte_sel[1])
224
          data[15:8] <= #Tp p_in[15:8];
225 13 simons
        if (byte_sel[2])
226
          data[23:16] <= #Tp p_in[23:16];
227 21 simons
        if (byte_sel[3])
228 15 simons
          data[`SPI_MAX_CHAR-1:24] <= #Tp p_in[`SPI_MAX_CHAR-1:24];
229
      `endif
230 13 simons
      end
231 7 simons
`endif
232 9 simons
`endif
233 2 simons
    else
234
      data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] <= #Tp rx_clk ? s_in : data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]];
235
  end
236
 
237
endmodule
238
 

powered by: WebSVN 2.1.0

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