diff options
Diffstat (limited to 'tests/iwls2005/ss_pcm/pcm_slv_top.v')
-rw-r--r-- | tests/iwls2005/ss_pcm/pcm_slv_top.v | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/tests/iwls2005/ss_pcm/pcm_slv_top.v b/tests/iwls2005/ss_pcm/pcm_slv_top.v new file mode 100644 index 000000000..2548d35fa --- /dev/null +++ b/tests/iwls2005/ss_pcm/pcm_slv_top.v @@ -0,0 +1,222 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// 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.2 2002/09/17 15:32:50 rudi Exp $ +// +// $Date: 2002/09/17 15:32:50 $ +// $Revision: 1.2 $ +// $Author: rudi $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: pcm_slv_top.v,v $ +// Revision 1.2 2002/09/17 15:32:50 rudi +// *** empty log message *** +// +// Revision 1.1.1.1 2002/09/17 15:17:25 rudi +// Initial Checkin +// +// +// +// +// +// +// +// + +`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 + |