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

Subversion Repositories ssp_slv

[/] [ssp_slv/] [trunk/] [RTL/] [SSPx_Slv.v] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 MichaelA
////////////////////////////////////////////////////////////////////////////////
2 2 MichaelA
//
3 3 MichaelA
//  Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates
4 2 MichaelA
//
5 3 MichaelA
//  All rights reserved. The source code contained herein is publicly released
6
//  under the terms and conditions of the GNU Lesser Public License. No part of
7
//  this source code may be reproduced or transmitted in any form or by any
8
//  means, electronic or mechanical, including photocopying, recording, or any
9
//  information storage and retrieval system in violation of the license under
10
//  which the source code is released.
11 2 MichaelA
//
12 3 MichaelA
//  The source code contained herein is free; it may be redistributed and/or
13
//  modified in accordance with the terms of the GNU Lesser General Public
14
//  License as published by the Free Software Foundation; either version 2.1 of
15
//  the GNU Lesser General Public License, or any later version.
16
//
17
//  The source code contained herein is freely released WITHOUT ANY WARRANTY;
18
//  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
19
//  PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for
20
//  more details.)
21
//
22
//  A copy of the GNU Lesser General Public License should have been received
23
//  along with the source code contained herein; if not, a copy can be obtained
24
//  by writing to:
25
//
26
//  Free Software Foundation, Inc.
27
//  51 Franklin Street, Fifth Floor
28
//  Boston, MA  02110-1301 USA
29
//
30 2 MichaelA
//  Further, no use of this source code is permitted in any form or means
31 3 MichaelA
//  without inclusion of this banner prominently in any derived works.
32 2 MichaelA
//
33
//  Michael A. Morris
34 3 MichaelA
//  Huntsville, AL
35 2 MichaelA
//
36 3 MichaelA
////////////////////////////////////////////////////////////////////////////////
37 2 MichaelA
 
38
`timescale 1ns / 1ps
39
 
40
///////////////////////////////////////////////////////////////////////////////
41
// Company:         M. A. Morris & Associates
42
// Engineer:        Michael A. Morris
43
//
44
// Create Date:     07:33 05/10/2008 
45 3 MichaelA
// Design Name:     Synchronous Serial Peripheral (SSP) Interface UART 
46
// Module Name:     ../VerilogCoponentsLib/SSP_UART/SSPx_Slv.v
47
// Project Name:    Verilog Components Library
48
// Target Devices:  XC3S50A-4VQG100I, XC3S20A-4VQG100I, XC3S700AN-4FFG484I
49 2 MichaelA
// Tool versions:   ISE 10.1i SP3 
50
//
51
// Description:
52
//
53
//  This module implements a full-duplex (Slave) SSP interface for 16-bit 
54
//  frames. In accordance to standard SPI practice, the module expects that
55
//  data is shifted into it MSB first. The first three bits are address bits,
56
//  the fourth bit is a command (WnR) bit which determines the operations to
57
//  be performed on the register, and the final twelve (12) bits are data bits.
58
//
59
// Dependencies:    None
60
//
61
// Revision History:
62
//
63
//  0.01    08E10   MAM     File Created
64
//
65
//  1.00    08E10   MAM     Initial Release
66
//
67
//  1.10    08G24   MAM     Modified the interface to operate with registered
68
//                          shift register data to eliminate transitions on
69
//                          MISO after risisng edge of SCK when input register
70
//                          written. Register RA[3:0] during fourth clock, and
71
//                          register DO[11:0] on falling edge of SCK after RA
72
//                          registered. This holds output data constant for the
73
//                          entire shift cycle.
74
//
75
//  1.11    11B01   MAM     Corrected #1 delay statement placement in register
76
//
77
//  2.00    11B06   MAM     Modified the interface to separate RA[3:1] and 
78
//                          RA[0] into RA[2:0] address port and a WnR command
79
//                          port. This makes the operation of the SSP/SPI I/F
80
//                          more clear.
81
//
82 3 MichaelA
//  2.10    13G06   MAM     Changed the asynchronous reset generated by ~SSEL.
83
//                          Previously, a number of internal circuits were 
84
//                          reset asynchronously on system reset, Rst, or ~SSEL.
85
//                          Added a FF, clocked on posedge SCK, that is asyn-
86
//                          chronously reset as before, but synchronously de-
87
//                          asserts on first rising edge of SCK. This signal,
88
//                          SSP_Rst, is used to asynchronously reset the same
89
//                          circuits as before: BC, EOC, and RDI. SPI Modes 0 or
90
//                          3 are still supported.
91
//
92
//  2.20    14D25   MAM     Encountered an issue whereby RA[2] held in reset
93
//                          after SSEL deasserted and then reasserted. The
94
//                          asynchronous reset on the signal SSP_Rst, a FF
95
//                          clocked on the falling edge of SCK, was changed to
96
//                          the combinatorial signal Rst_SSP. Rst_SSP is the
97
//                          source of the asynchronous reset of the SSP_Rst FF.
98
//                          The additional delay in the SSP_Rst signal caused
99
//                          RA[2] to be kept in reset at the start of a new
100
//                          SSP transfer cycle. Also added two additional CE
101
//                          signals while tracking down this issue: CE_RA and
102
//                          CE_WnR. They were previously driven directly by the
103
//                          bit counter.
104
//
105 2 MichaelA
// Additional Comments: 
106
//
107 3 MichaelA
////////////////////////////////////////////////////////////////////////////////
108 2 MichaelA
 
109
module SSPx_Slv(
110
    input   Rst,            // System Reset
111
//
112
    input   SSEL,           // Slave Select
113
    input   SCK,            // Shift Clock
114
    input   MOSI,           // Master Out, Slave In: Serial Data In
115
    output  reg MISO,       // Master In, Slave Out: Serial Data Out
116
//
117
    output  reg [2:0] RA,   // SSP Register Address output
118
    output  reg WnR,        // SSP Command: 1 - Write, 0 - Read
119
    output  En,             // SSP Enable - asserted during field
120
    output  reg EOC,        // SSP End of Cycle - asserted on last bit of frame
121
    output  reg [11:0] DI,  // Input shift register output
122
    input   [11:0] DO,      // Output shift register input
123
//
124
    output  reg [3:0] BC    // Bit Count, 0 - MSB; 15 - LSB
125
);
126
 
127
///////////////////////////////////////////////////////////////////////////////    
128
//
129
//  Local Declarations
130
//
131
 
132
    reg     [15:1] RDI; // Serial Input Shift Register
133
    reg     [11:0] rDO; // output data register
134
 
135 3 MichaelA
    reg     SSP_Rst;
136
 
137 2 MichaelA
///////////////////////////////////////////////////////////////////////////////
138
//
139
//  Implementation
140
//
141
 
142
//  Module Reset - asynchronous because SCK not continuous
143
 
144
assign Rst_SSP = (Rst | ~SSEL);
145
 
146 3 MichaelA
always @(posedge SCK or posedge Rst_SSP)
147
begin
148
    if(Rst_SSP)
149
        SSP_Rst <= #1 ~0;
150
    else
151
        SSP_Rst <= #1  0;
152
end
153
 
154 2 MichaelA
//  Bit Counter, count from 0 to 15
155
//      Clock on negedge SCK to align MISO in bit cell
156
 
157 3 MichaelA
always @(negedge SCK or posedge SSP_Rst)
158 2 MichaelA
begin
159 3 MichaelA
    if(SSP_Rst)
160 2 MichaelA
        BC <= #1 4'd0;
161
    else
162
        BC <= #1 (BC + 1);
163
end
164
 
165
//  End-Of-Cycle, asserted during last bit of transfer (bit 15)
166
//      Clock on negedge SCK to center rising edge in bit cell
167
 
168 3 MichaelA
always @(negedge SCK or posedge SSP_Rst)
169 2 MichaelA
begin
170 3 MichaelA
    if(SSP_Rst)
171 2 MichaelA
        EOC <= #1 1'b0;
172
    else
173
        EOC <= #1 (BC == 14);
174
end
175
 
176
//  Generate SSP Enable, require four bits for internal addressing
177
 
178
assign En = BC[3] | BC[2];
179
 
180
//  Load MOSI into RDI using BC to select the active register
181
//      Use posedge SCK to sample in middle of bit cell
182
 
183
always @(posedge SCK or posedge Rst_SSP)
184
begin
185
    if(Rst_SSP)
186
        RDI <= #1 15'b0;
187
    else
188
        case(BC)
189 3 MichaelA
            4'b0000 : RDI[15] <= #1 MOSI;
190
            4'b0001 : RDI[14] <= #1 MOSI;
191
            4'b0010 : RDI[13] <= #1 MOSI;
192
            4'b0011 : RDI[12] <= #1 MOSI;
193
            4'b0100 : RDI[11] <= #1 MOSI;
194
            4'b0101 : RDI[10] <= #1 MOSI;
195
            4'b0110 : RDI[ 9] <= #1 MOSI;
196
            4'b0111 : RDI[ 8] <= #1 MOSI;
197
            4'b1000 : RDI[ 7] <= #1 MOSI;
198
            4'b1001 : RDI[ 6] <= #1 MOSI;
199
            4'b1010 : RDI[ 5] <= #1 MOSI;
200
            4'b1011 : RDI[ 4] <= #1 MOSI;
201
            4'b1100 : RDI[ 3] <= #1 MOSI;
202
            4'b1101 : RDI[ 2] <= #1 MOSI;
203
            4'b1110 : RDI[ 1] <= #1 MOSI;
204
            default : RDI <= #1 RDI;
205 2 MichaelA
        endcase
206
end
207
 
208
//  Assign RA, WnR, and DI bus from RDI and MOSI
209
 
210 3 MichaelA
assign CE_RA = (BC == 2);
211 2 MichaelA
 
212 3 MichaelA
always @(negedge SCK or posedge Rst_SSP)
213 2 MichaelA
begin
214 3 MichaelA
    if(Rst_SSP)
215 2 MichaelA
        RA <= #1 0;
216 3 MichaelA
    else if(CE_RA)
217 2 MichaelA
        RA <= #1 RDI[15:13];
218
end
219
 
220 3 MichaelA
assign CE_WnR = (BC == 3);
221
 
222
always @(negedge SCK or posedge Rst_SSP)
223 2 MichaelA
begin
224 3 MichaelA
    if(Rst_SSP)
225 2 MichaelA
        WnR <= #1 0;
226
    else if(EOC)
227
        WnR <= #1 0;
228 3 MichaelA
    else if(CE_WnR)
229 2 MichaelA
        WnR <= #1 RDI[12];
230
end
231
 
232 3 MichaelA
always @(*) DI <= {RDI[11:1], MOSI};
233 2 MichaelA
 
234
always @(negedge SCK or posedge Rst)
235
begin
236
    if(Rst)
237
        rDO <= #1 0;
238
    else if(BC == 3)
239
        rDO <= #1 DO;
240
end
241
 
242
// Generate MISO: multiplex MOSI and DO using En and BC
243
 
244 3 MichaelA
always @(*)
245 2 MichaelA
begin
246
    case(BC)
247
        4'b0000 :   MISO <= MOSI;
248
        4'b0001 :   MISO <= MOSI;
249
        4'b0010 :   MISO <= MOSI;
250
        4'b0011 :   MISO <= MOSI;
251
        4'b0100 :   MISO <= rDO[11];
252
        4'b0101 :   MISO <= rDO[10];
253
        4'b0110 :   MISO <= rDO[ 9];
254
        4'b0111 :   MISO <= rDO[ 8];
255
        4'b1000 :   MISO <= rDO[ 7];
256
        4'b1001 :   MISO <= rDO[ 6];
257
        4'b1010 :   MISO <= rDO[ 5];
258
        4'b1011 :   MISO <= rDO[ 4];
259
        4'b1100 :   MISO <= rDO[ 3];
260
        4'b1101 :   MISO <= rDO[ 2];
261
        4'b1110 :   MISO <= rDO[ 1];
262
        4'b1111 :   MISO <= rDO[ 0];
263
    endcase
264
end
265
 
266
endmodule

powered by: WebSVN 2.1.0

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