OpenCores
URL https://opencores.org/ocsvn/ssp_slv/ssp_slv/trunk
//////////////////////////////////////////////////////////////////////////////// // // Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates // // All rights reserved. The source code contained herein is publicly released // under the terms and conditions of the GNU Lesser Public License. No part of // this source code may be reproduced or transmitted in any form or by any // means, electronic or mechanical, including photocopying, recording, or any // information storage and retrieval system in violation of the license under // which the source code is released. // // The source code contained herein is free; it may be redistributed and/or // modified in accordance with the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either version 2.1 of // the GNU Lesser General Public License, or any later version. // // The source code contained herein is freely released WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A // PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for // more details.) // // A copy of the GNU Lesser General Public License should have been received // along with the source code contained herein; if not, a copy can be obtained // by writing to: // // Free Software Foundation, Inc. // 51 Franklin Street, Fifth Floor // Boston, MA 02110-1301 USA // // Further, no use of this source code is permitted in any form or means // without inclusion of this banner prominently in any derived works. // // Michael A. Morris // Huntsville, AL // //////////////////////////////////////////////////////////////////////////////// `timescale 1ns / 1ps /////////////////////////////////////////////////////////////////////////////// // Company: M. A. Morris & Associates // Engineer: Michael A. Morris // // Create Date: 07:33 05/10/2008 // Design Name: Synchronous Serial Peripheral (SSP) Interface UART // Module Name: ../VerilogCoponentsLib/SSP_UART/SSPx_Slv.v // Project Name: Verilog Components Library // Target Devices: XC3S50A-4VQG100I, XC3S20A-4VQG100I, XC3S700AN-4FFG484I // Tool versions: ISE 10.1i SP3 // // Description: // // This module implements a full-duplex (Slave) SSP interface for 16-bit // frames. In accordance to standard SPI practice, the module expects that // data is shifted into it MSB first. The first three bits are address bits, // the fourth bit is a command (WnR) bit which determines the operations to // be performed on the register, and the final twelve (12) bits are data bits. // // Dependencies: None // // Revision History: // // 0.01 08E10 MAM File Created // // 1.00 08E10 MAM Initial Release // // 1.10 08G24 MAM Modified the interface to operate with registered // shift register data to eliminate transitions on // MISO after risisng edge of SCK when input register // written. Register RA[3:0] during fourth clock, and // register DO[11:0] on falling edge of SCK after RA // registered. This holds output data constant for the // entire shift cycle. // // 1.11 11B01 MAM Corrected #1 delay statement placement in register // // 2.00 11B06 MAM Modified the interface to separate RA[3:1] and // RA[0] into RA[2:0] address port and a WnR command // port. This makes the operation of the SSP/SPI I/F // more clear. // // 2.10 13G06 MAM Changed the asynchronous reset generated by ~SSEL. // Previously, a number of internal circuits were // reset asynchronously on system reset, Rst, or ~SSEL. // Added a FF, clocked on posedge SCK, that is asyn- // chronously reset as before, but synchronously de- // asserts on first rising edge of SCK. This signal, // SSP_Rst, is used to asynchronously reset the same // circuits as before: BC, EOC, and RDI. SPI Modes 0 or // 3 are still supported. // // 2.20 14D25 MAM Encountered an issue whereby RA[2] held in reset // after SSEL deasserted and then reasserted. The // asynchronous reset on the signal SSP_Rst, a FF // clocked on the falling edge of SCK, was changed to // the combinatorial signal Rst_SSP. Rst_SSP is the // source of the asynchronous reset of the SSP_Rst FF. // The additional delay in the SSP_Rst signal caused // RA[2] to be kept in reset at the start of a new // SSP transfer cycle. Also added two additional CE // signals while tracking down this issue: CE_RA and // CE_WnR. They were previously driven directly by the // bit counter. // // Additional Comments: // //////////////////////////////////////////////////////////////////////////////// module SSPx_Slv( input Rst, // System Reset // input SSEL, // Slave Select input SCK, // Shift Clock input MOSI, // Master Out, Slave In: Serial Data In output reg MISO, // Master In, Slave Out: Serial Data Out // output reg [2:0] RA, // SSP Register Address output output reg WnR, // SSP Command: 1 - Write, 0 - Read output En, // SSP Enable - asserted during field output reg EOC, // SSP End of Cycle - asserted on last bit of frame output reg [11:0] DI, // Input shift register output input [11:0] DO, // Output shift register input // output reg [3:0] BC // Bit Count, 0 - MSB; 15 - LSB ); /////////////////////////////////////////////////////////////////////////////// // // Local Declarations // reg [15:1] RDI; // Serial Input Shift Register reg [11:0] rDO; // output data register reg SSP_Rst; /////////////////////////////////////////////////////////////////////////////// // // Implementation // // Module Reset - asynchronous because SCK not continuous assign Rst_SSP = (Rst | ~SSEL); always @(posedge SCK or posedge Rst_SSP) begin if(Rst_SSP) SSP_Rst <= #1 ~0; else SSP_Rst <= #1 0; end // Bit Counter, count from 0 to 15 // Clock on negedge SCK to align MISO in bit cell always @(negedge SCK or posedge SSP_Rst) begin if(SSP_Rst) BC <= #1 4'd0; else BC <= #1 (BC + 1); end // End-Of-Cycle, asserted during last bit of transfer (bit 15) // Clock on negedge SCK to center rising edge in bit cell always @(negedge SCK or posedge SSP_Rst) begin if(SSP_Rst) EOC <= #1 1'b0; else EOC <= #1 (BC == 14); end // Generate SSP Enable, require four bits for internal addressing assign En = BC[3] | BC[2]; // Load MOSI into RDI using BC to select the active register // Use posedge SCK to sample in middle of bit cell always @(posedge SCK or posedge Rst_SSP) begin if(Rst_SSP) RDI <= #1 15'b0; else case(BC) 4'b0000 : RDI[15] <= #1 MOSI; 4'b0001 : RDI[14] <= #1 MOSI; 4'b0010 : RDI[13] <= #1 MOSI; 4'b0011 : RDI[12] <= #1 MOSI; 4'b0100 : RDI[11] <= #1 MOSI; 4'b0101 : RDI[10] <= #1 MOSI; 4'b0110 : RDI[ 9] <= #1 MOSI; 4'b0111 : RDI[ 8] <= #1 MOSI; 4'b1000 : RDI[ 7] <= #1 MOSI; 4'b1001 : RDI[ 6] <= #1 MOSI; 4'b1010 : RDI[ 5] <= #1 MOSI; 4'b1011 : RDI[ 4] <= #1 MOSI; 4'b1100 : RDI[ 3] <= #1 MOSI; 4'b1101 : RDI[ 2] <= #1 MOSI; 4'b1110 : RDI[ 1] <= #1 MOSI; default : RDI <= #1 RDI; endcase end // Assign RA, WnR, and DI bus from RDI and MOSI assign CE_RA = (BC == 2); always @(negedge SCK or posedge Rst_SSP) begin if(Rst_SSP) RA <= #1 0; else if(CE_RA) RA <= #1 RDI[15:13]; end assign CE_WnR = (BC == 3); always @(negedge SCK or posedge Rst_SSP) begin if(Rst_SSP) WnR <= #1 0; else if(EOC) WnR <= #1 0; else if(CE_WnR) WnR <= #1 RDI[12]; end always @(*) DI <= {RDI[11:1], MOSI}; always @(negedge SCK or posedge Rst) begin if(Rst) rDO <= #1 0; else if(BC == 3) rDO <= #1 DO; end // Generate MISO: multiplex MOSI and DO using En and BC always @(*) begin case(BC) 4'b0000 : MISO <= MOSI; 4'b0001 : MISO <= MOSI; 4'b0010 : MISO <= MOSI; 4'b0011 : MISO <= MOSI; 4'b0100 : MISO <= rDO[11]; 4'b0101 : MISO <= rDO[10]; 4'b0110 : MISO <= rDO[ 9]; 4'b0111 : MISO <= rDO[ 8]; 4'b1000 : MISO <= rDO[ 7]; 4'b1001 : MISO <= rDO[ 6]; 4'b1010 : MISO <= rDO[ 5]; 4'b1011 : MISO <= rDO[ 4]; 4'b1100 : MISO <= rDO[ 3]; 4'b1101 : MISO <= rDO[ 2]; 4'b1110 : MISO <= rDO[ 1]; 4'b1111 : MISO <= rDO[ 0]; endcase end endmodule

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

powered by: WebSVN 2.1.0

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