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

Subversion Repositories spdif_transmitter

[/] [spdif_transmitter/] [trunk/] [rtl/] [spdif_core.v] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 ultra_embe
//-----------------------------------------------------------------
2
//                        SPDIF Transmitter
3
//                              V0.1
4
//                        Ultra-Embedded.com
5
//                          Copyright 2012
6
//
7
//                 Email: admin@ultra-embedded.com
8
//
9
//                         License: GPL
10
// If you would like a version with a more permissive license for
11
// use in closed source commercial applications please contact me
12
// for details.
13
//-----------------------------------------------------------------
14
//
15
// This file is open source HDL; you can redistribute it and/or 
16
// modify it under the terms of the GNU General Public License as 
17
// published by the Free Software Foundation; either version 2 of 
18
// the License, or (at your option) any later version.
19
//
20
// This file is distributed in the hope that it will be useful,
21
// but WITHOUT ANY WARRANTY; without even the implied warranty of
22
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
// GNU General Public License for more details.
24
//
25
// You should have received a copy of the GNU General Public 
26
// License along with this file; if not, write to the Free Software
27
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28
// USA
29
//-----------------------------------------------------------------
30
module spdif_core
31
(
32
    input           clk_i,
33
    input           rst_i,
34
 
35
    // SPDIF bit output enable
36
    // Single cycle pulse synchronous to clk_i which drives
37
    // the output bit rate.
38
    // For 44.1KHz, 44100×32×2×2 = 5,644,800Hz
39
    // For 48KHz,   48000×32×2×2 = 6,144,000Hz
40
    input           bit_out_en_i,
41
 
42
    // Output
43
    output          spdif_o,
44
 
45
    // Audio interface (16-bit x 2 = RL)
46
    input [31:0]    sample_i,
47
    output reg      sample_req_o
48
);
49
 
50
//-----------------------------------------------------------------
51
// Registers
52
//-----------------------------------------------------------------
53
reg [15:0]  audio_sample_q;
54
reg [8:0]   subframe_count_q;
55
 
56
reg         load_subframe_q;
57
reg [7:0]   preamble_q;
58
wire [31:0] subframe_w;
59
 
60
reg [5:0]   bit_count_q;
61
reg         bit_toggle_q;
62
 
63
// Xilinx: Place output flop in IOB
64
//synthesis attribute IOB of spdif_out_q is "TRUE"
65
reg         spdif_out_q;
66
 
67
reg [5:0]   parity_count_q;
68
 
69
//-----------------------------------------------------------------
70
// Subframe Counter
71
//-----------------------------------------------------------------
72
always @ (posedge rst_i or posedge clk_i )
73
begin
74
    if (rst_i == 1'b1)
75
        subframe_count_q    <= 9'd0;
76
    else if (load_subframe_q)
77
    begin
78
        // 192 frames (384 subframes) in an audio block
79
        if (subframe_count_q == 9'd383)
80
            subframe_count_q <= 9'd0;
81
        else
82
            subframe_count_q <= subframe_count_q + 9'd1;
83
    end
84
end
85
 
86
//-----------------------------------------------------------------
87
// Sample capture
88
//-----------------------------------------------------------------
89
reg [15:0] sample_buf_q;
90
 
91
always @ (posedge rst_i or posedge clk_i )
92
begin
93
   if (rst_i == 1'b1)
94
   begin
95
        audio_sample_q      <= 16'h0000;
96
        sample_buf_q        <= 16'h0000;
97
        sample_req_o        <= 1'b0;
98
   end
99
   else if (load_subframe_q)
100
   begin
101
        // Start of frame (first subframe)?
102
        if (subframe_count_q[0] == 1'b0)
103
        begin
104
            // Use left sample
105
            audio_sample_q <= sample_i[15:0];
106
 
107
            // Store right sample
108
            sample_buf_q <= sample_i[31:16];
109
 
110
            // Request next sample
111
            sample_req_o <= 1'b1;
112
        end
113
        else
114
        begin
115
            // Use right sample
116
            audio_sample_q <= sample_buf_q;
117
 
118
            sample_req_o <= 1'b0;
119
        end
120
   end
121
   else
122
        sample_req_o <= 1'b0;
123
end
124
 
125
// Timeslots 3 - 0 = Preamble
126
assign subframe_w[3:0] = 4'b0000;
127
 
128
// Timeslots 7 - 4 = 24-bit audio LSB
129
assign subframe_w[7:4] = 4'b0000;
130
 
131
// Timeslots 11 - 8 = 20-bit audio LSB
132
assign subframe_w[11:8] = 4'b0000;
133
 
134
// Timeslots 27 - 12 = 16-bit audio
135
assign subframe_w[27:12] = audio_sample_q;
136
 
137
// Timeslots 28 = Validity
138
assign subframe_w[28] = 1'b0; // Valid
139
 
140
// Timeslots 29 = User bit
141
assign subframe_w[29] = 1'b0;
142
 
143
// Timeslots 30 = Channel status bit
144
assign subframe_w[30] = 1'b0;
145
 
146
// Timeslots 31 = Even Parity bit (31:4)
147
assign subframe_w[31] = 1'b0;
148
 
149
//-----------------------------------------------------------------
150
// Preamble
151
//-----------------------------------------------------------------
152
localparam PREAMBLE_Z = 8'b00010111;
153
localparam PREAMBLE_Y = 8'b00100111;
154
localparam PREAMBLE_X = 8'b01000111;
155
 
156
reg [7:0] preamble_r;
157
 
158
always @ *
159
begin
160
    // Start of audio block?
161
    // Z(B) - Left channel
162
    if (subframe_count_q == 9'd0)
163
        preamble_r = PREAMBLE_Z; // Z(B)
164
    // Right Channel?
165
    else if (subframe_count_q[0] == 1'b1)
166
        preamble_r = PREAMBLE_Y; // Y(W)
167
    // Left Channel (but not start of block)?
168
    else
169
        preamble_r = PREAMBLE_X; // X(M)
170
 
171
    // If previous timeslot ended with a 1, invert preamble
172
    if (spdif_o)
173
        preamble_r = ~preamble_r;
174
end
175
 
176
always @ (posedge rst_i or posedge clk_i )
177
if (rst_i == 1'b1)
178
    preamble_q  <= 8'h00;
179
else if (load_subframe_q)
180
    preamble_q  <= preamble_r;
181
 
182
//-----------------------------------------------------------------
183
// Parity Counter
184
//-----------------------------------------------------------------
185
always @ (posedge rst_i or posedge clk_i )
186
begin
187
   if (rst_i == 1'b1)
188
   begin
189
        parity_count_q  <= 6'd0;
190
   end
191
   // Time to output a bit?
192
   else if (bit_out_en_i)
193
   begin
194
        // Preamble bits?
195
        if (bit_count_q < 6'd8)
196
        begin
197
            parity_count_q  <= 6'd0;
198
        end
199
        // Normal timeslots
200
        else if (bit_count_q < 6'd62)
201
        begin
202
            // On first pass through this timeslot, count number of high bits
203
            if (bit_count_q[0] == 0 && subframe_w[bit_count_q / 2] == 1'b1)
204
                parity_count_q <= parity_count_q + 6'd1;
205
        end
206
   end
207
end
208
 
209
//-----------------------------------------------------------------
210
// Bit Counter
211
//-----------------------------------------------------------------
212
always @ (posedge rst_i or posedge clk_i)
213
begin
214
    if (rst_i == 1'b1)
215
    begin
216
        bit_count_q     <= 6'b0;
217
        load_subframe_q <= 1'b1;
218
    end
219
    // Time to output a bit?
220
    else if (bit_out_en_i)
221
    begin
222
        // 32 timeslots (x2 for double frequency)
223
        if (bit_count_q == 6'd63)
224
        begin
225
            bit_count_q     <= 6'd0;
226
            load_subframe_q <= 1'b1;
227
        end
228
        else
229
        begin
230
            bit_count_q     <= bit_count_q + 6'd1;
231
            load_subframe_q <= 1'b0;
232
        end
233
    end
234
    else
235
        load_subframe_q <= 1'b0;
236
end
237
 
238
//-----------------------------------------------------------------
239
// Bit half toggle
240
//-----------------------------------------------------------------
241
always @ (posedge rst_i or posedge clk_i)
242
if (rst_i == 1'b1)
243
    bit_toggle_q    <= 1'b0;
244
// Time to output a bit?
245
else if (bit_out_en_i)
246
    bit_toggle_q <= ~bit_toggle_q;
247
 
248
//-----------------------------------------------------------------
249
// Output bit (BMC encoded)
250
//-----------------------------------------------------------------
251
reg bit_r;
252
 
253
always @ *
254
begin
255
    bit_r = spdif_out_q;
256
 
257
    // Time to output a bit?
258
    if (bit_out_en_i)
259
    begin
260
        // Preamble bits?
261
        if (bit_count_q < 6'd8)
262
        begin
263
            bit_r = preamble_q[bit_count_q[2:0]];
264
        end
265
        // Normal timeslots
266
        else if (bit_count_q < 6'd62)
267
        begin
268
            if (subframe_w[bit_count_q / 2] == 1'b0)
269
            begin
270
                if (bit_toggle_q == 1'b0)
271
                    bit_r = ~spdif_out_q;
272
                else
273
                    bit_r = spdif_out_q;
274
            end
275
            else
276
                bit_r = ~spdif_out_q;
277
        end
278
        // Parity timeslot
279
        else
280
        begin
281
            // Even number of high bits, make odd
282
            if (parity_count_q[0] == 1'b0)
283
            begin
284
                if (bit_toggle_q == 1'b0)
285
                    bit_r = ~spdif_out_q;
286
                else
287
                    bit_r = spdif_out_q;
288
            end
289
            else
290
                bit_r = ~spdif_out_q;
291
        end
292
    end
293
end
294
 
295
always @ (posedge rst_i or posedge clk_i )
296
if (rst_i == 1'b1)
297
    spdif_out_q <= 1'b0;
298
else
299
    spdif_out_q <= bit_r;
300
 
301
assign spdif_o  = spdif_out_q;
302
 
303
endmodule

powered by: WebSVN 2.1.0

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