URL
https://opencores.org/ocsvn/ss_pcm/ss_pcm/trunk
Subversion Repositories ss_pcm
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/tags/start/rtl/verilog/pcm_slv_top.v
0,0 → 1,217
///////////////////////////////////////////////////////////////////// |
//// //// |
//// PCM IO Slave Module //// |
//// //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// //// |
//// Downloaded from: http://www.opencores.org/cores/ss_pcm/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000-2002 Rudolf Usselmann //// |
//// www.asics.ws //// |
//// rudi@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: pcm_slv_top.v,v 1.1.1.1 2002-09-17 15:17:25 rudi Exp $ |
// |
// $Date: 2002-09-17 15:17:25 $ |
// $Revision: 1.1.1.1 $ |
// $Author: rudi $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// |
// |
// |
// |
// |
// |
// |
|
`include "timescale.v" |
|
/* |
PCM Interface |
=============================== |
PCM_CLK |
PCM_SYNC |
PCM_DIN |
PCM_DOUT |
*/ |
|
|
module pcm_slv_top( clk, rst, |
|
ssel, |
|
// PCM |
pcm_clk_i, pcm_sync_i, pcm_din_i, pcm_dout_o, |
|
// Internal Interface |
din_i, dout_o, re_i, we_i); |
|
input clk, rst; |
input [2:0] ssel; // Number of bits to delay (0-7) |
input pcm_clk_i, pcm_sync_i, pcm_din_i; |
output pcm_dout_o; |
input [7:0] din_i; |
output [7:0] dout_o; |
input re_i; |
input [1:0] we_i; |
|
/////////////////////////////////////////////////////////////////// |
// |
// Local Wires and Registers |
// |
|
reg pclk_t, pclk_s, pclk_r; |
wire pclk_ris, pclk_fal; |
reg psync; |
reg pcm_sync_r1, pcm_sync_r2, pcm_sync_r3; |
reg tx_go; |
wire tx_data_le; |
reg [15:0] tx_hold_reg; |
reg [7:0] tx_hold_byte_h, tx_hold_byte_l; |
reg [3:0] tx_cnt; |
wire tx_done; |
reg [15:0] rx_hold_reg, rx_reg; |
wire rx_data_le; |
reg rxd_t, rxd; |
reg tx_go_r1, tx_go_r2; |
reg [7:0] psa; |
|
/////////////////////////////////////////////////////////////////// |
// |
// Misc Logic |
// |
|
always @(posedge clk) |
pclk_t <= #1 pcm_clk_i; |
|
always @(posedge clk) |
pclk_s <= #1 pclk_t; |
|
always @(posedge clk) |
pclk_r <= #1 pclk_s; |
|
assign pclk_ris = !pclk_r & pclk_s; |
assign pclk_fal = pclk_r & !pclk_s; |
|
/////////////////////////////////////////////////////////////////// |
// |
// Retrieve Sync Signal |
// |
|
always @(posedge clk) // Latch it at falling edge |
if(pclk_fal) pcm_sync_r1 <= #1 pcm_sync_i; |
|
always @(posedge clk) // resync to rising edge |
if(pclk_ris) psa <= #1 {psa[6:0], pcm_sync_r1}; |
|
always @(posedge clk) //delay bit N |
pcm_sync_r2 <= #1 psa[ssel]; |
|
always @(posedge clk) // edge detector |
pcm_sync_r3 <= #1 pcm_sync_r2; |
|
always @(posedge clk) |
psync <= #1 !pcm_sync_r3 & pcm_sync_r2; |
|
/////////////////////////////////////////////////////////////////// |
// |
// Transmit Logic |
// |
|
assign tx_data_le = tx_go & pclk_ris; |
|
always @(posedge clk) |
if(we_i[1]) tx_hold_byte_h <= #1 din_i; |
|
always @(posedge clk) |
if(we_i[0]) tx_hold_byte_l <= #1 din_i; |
|
always @(posedge clk) |
if(!rst) tx_go <= #1 1'b0; |
else |
if(psync) tx_go <= #1 1'b1; |
else |
if(tx_done) tx_go <= #1 1'b0; |
|
always @(posedge clk) |
if(!rst) tx_hold_reg <= #1 16'h0; |
else |
if(psync) tx_hold_reg <= #1 {tx_hold_byte_h, tx_hold_byte_l}; |
else |
if(tx_data_le) tx_hold_reg <= #1 {tx_hold_reg[14:0],1'b0}; |
|
assign pcm_dout_o = tx_hold_reg[15]; |
|
always @(posedge clk) |
if(!rst) tx_cnt <= #1 4'h0; |
else |
if(tx_data_le) tx_cnt <= tx_cnt + 4'h1; |
|
assign tx_done = (tx_cnt == 4'hf) & tx_data_le; |
|
/////////////////////////////////////////////////////////////////// |
// |
// Recieve Logic |
// |
|
always @(posedge clk) |
if(pclk_ris) tx_go_r1 <= #1 tx_go; |
|
always @(posedge clk) |
if(pclk_ris) tx_go_r2 <= #1 tx_go_r1; |
|
// Receive is in sync with transmit ... |
always @(posedge clk) |
if(pclk_fal) rxd_t <= #1 pcm_din_i; |
|
always @(posedge clk) |
rxd <= #1 rxd_t; |
|
assign rx_data_le = (tx_go_r1 | tx_go) & pclk_fal; |
|
always @(posedge clk) |
if(!rst) rx_hold_reg <= #1 16'h0; |
else |
if(rx_data_le) rx_hold_reg <= #1 {rx_hold_reg[14:0], rxd}; |
|
always @(posedge clk) |
if(!rst) rx_reg <= #1 16'h0; |
else |
if(tx_go_r1 & !tx_go & pclk_ris) rx_reg <= #1 rx_hold_reg; |
|
assign dout_o = re_i ? rx_reg[15:8] : rx_reg[7:0]; |
|
endmodule |
|
/tags/start/rtl/verilog/timescale.v
0,0 → 1,217
`timescale 1ns / 10ps |
/tags/start/doc/README.txt
0,0 → 1,114
|
SS_PCM (Single Slot Slave PCM Intervace) |
============================================ |
|
Status |
------ |
This core is done. It was tested on a XESS XCV800 board |
interfacing to a proprietary device with a TI DSP, exchanging |
PCM streams in both directions. |
|
Test Bench |
---------- |
There is no test bench, period ! |
Please don't email me asking for one, unless you want to hire |
me to write one ! As I said above I have tested this core in |
real hardware and it works just fine. |
|
Documentation |
------------- |
Sorry, there is none. I just don't have the time to write it. |
|
Here is a short how to: |
|
This is a Salve PCM interface, meaning Clock and Sync are input |
to the core. To make it a Master interface add a clock and Sync |
signal generator (for example a 128KHz clock and 8KHz Sync). |
|
PCM Clock is an external clock source and can really be any |
clock rate. It should however be 16 times faster than the PCM |
Sync signal rate. |
|
PCM Sync, indicates the start of a PCM frame and in a practical |
application would come in 8KHz intervals. |
|
SSEL, indicates how many clock cycles to wait after a Sync |
signal before starting to receive and transmit data. |
|
After seeing a the Sync signal, this core will wait 'SSEL' |
number of PCM clock cycles and then start receiving and |
transmitting. Receiving and transmitting always happens |
simultaneously. After it has finished receiving and transmitting |
16 bits it will wait for the next Sync signal before repeating |
the process. |
|
At the end of receive process data is transferred from a |
shift register to a hold register, guaranteeing that the data |
will only change once during one Sync period. |
After seeing the Sync signal, data is transferred from a transmit |
holding register to a transmit shift register. If the transmit |
hold register is not updates during one sync period the previous |
data is retransmitted. |
|
All of the above behavior is in compliance with general PCM |
stream usage. |
|
The core itself has a 8 bit interface. 're_i' selects between |
the high and low byte in the holding register: |
re_i-1 High byte from the receive holding register is driven |
on dout_o |
re_i-0 Low byte from the receive holding register is driven |
on dout_o |
|
To write data to the core: |
we_i[0]-1 Stores data from din_i to transmit hold |
register low byte |
we_i[1]-1 Stores data from din_i to transmit hold |
register high byte |
|
|
|
Misc |
---- |
The SASC Project Page is: |
http://www.opencores.org/cores/sasc/ |
|
To find out more about me (Rudolf Usselmann), please visit: |
http://www.asics.ws |
|
|
Directory Structure |
------------------- |
[core_root] |
| |
+-doc Documentation |
| |
+-bench--+ Test Bench |
| +- verilog Verilog Sources |
| +-vhdl VHDL Sources |
| |
+-rtl----+ Core RTL Sources |
| +-verilog Verilog Sources |
| +-vhdl VHDL Sources |
| |
+-sim----+ |
| +-rtl_sim---+ Functional verification Directory |
| | +-bin Makefiles/Run Scripts |
| | +-run Working Directory |
| | |
| +-gate_sim--+ Functional & Timing Gate Level |
| | Verification Directory |
| +-bin Makefiles/Run Scripts |
| +-run Working Directory |
| |
+-lint--+ Lint Directory Tree |
| +-bin Makefiles/Run Scripts |
| +-run Working Directory |
| +-log Linter log & result files |
| |
+-syn---+ Synthesis Directory Tree |
| +-bin Synthesis Scripts |
| +-run Working Directory |
| +-log Synthesis log files |
| +-out Synthesis Output |
|