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

Subversion Repositories sasc

[/] [sasc/] [trunk/] [rtl/] [verilog/] [sasc_top.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rudi
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  Simple Asynchronous Serial Comm. Device                    ////
4
////                                                             ////
5
////                                                             ////
6
////  Author: Rudolf Usselmann                                   ////
7
////          rudi@asics.ws                                      ////
8
////                                                             ////
9
////                                                             ////
10
////  Downloaded from: http://www.opencores.org/cores/sasc/      ////
11
////                                                             ////
12
/////////////////////////////////////////////////////////////////////
13
////                                                             ////
14
//// Copyright (C) 2000-2002 Rudolf Usselmann                    ////
15
////                         www.asics.ws                        ////
16
////                         rudi@asics.ws                       ////
17
////                                                             ////
18
//// This source file may be used and distributed without        ////
19
//// restriction provided that this copyright statement is not   ////
20
//// removed from the file and that any derivative work contains ////
21
//// the original copyright notice and the associated disclaimer.////
22
////                                                             ////
23
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
24
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
25
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
26
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
27
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
28
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
29
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
30
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
31
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
32
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
33
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
34
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
35
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
36
////                                                             ////
37
/////////////////////////////////////////////////////////////////////
38
 
39
//  CVS Log
40
//
41 5 rudi
//  $Id: sasc_top.v,v 1.2 2006-03-30 02:47:07 rudi Exp $
42 2 rudi
//
43 5 rudi
//  $Date: 2006-03-30 02:47:07 $
44
//  $Revision: 1.2 $
45 2 rudi
//  $Author: rudi $
46
//  $Locker:  $
47
//  $State: Exp $
48
//
49
// Change History:
50
//               $Log: not supported by cvs2svn $
51 5 rudi
//               Revision 1.1.1.1  2002/09/16 16:16:42  rudi
52
//               Initial Checkin
53 2 rudi
//
54
//
55
//
56
//
57
//
58
//
59
//
60 5 rudi
//
61 2 rudi
 
62
`include "timescale.v"
63
 
64
/*
65
Serial IO Interface
66
===============================
67
RTS I Request To Send
68
CTS O Clear to send
69
TD  I Transmit Data
70
RD  O Receive Data
71
*/
72
 
73
module sasc_top(        clk, rst,
74
 
75
                        // SIO
76
                        rxd_i, txd_o, cts_i, rts_o,
77
 
78
                        // External Baud Rate Generator
79
                        sio_ce, sio_ce_x4,
80
 
81
                        // Internal Interface
82
                        din_i, dout_o, re_i, we_i, full_o, empty_o);
83
 
84
input           clk;
85
input           rst;
86
input           rxd_i;
87
output          txd_o;
88
input           cts_i;
89
output          rts_o;
90
input           sio_ce;
91
input           sio_ce_x4;
92
input   [7:0]    din_i;
93
output  [7:0]    dout_o;
94
input           re_i, we_i;
95
output          full_o, empty_o;
96
 
97
///////////////////////////////////////////////////////////////////
98
//
99
// Local Wires and Registers
100
//
101
 
102
parameter       START_BIT       = 1'b0,
103
                STOP_BIT        = 1'b1,
104
                IDLE_BIT        = 1'b1;
105
 
106
wire    [7:0]    txd_p;
107
reg             load;
108
reg             load_r;
109
wire            load_e;
110
reg     [9:0]    hold_reg;
111
wire            txf_empty;
112
reg             txd_o;
113
reg             shift_en;
114
reg     [3:0]    tx_bit_cnt;
115
reg             rxd_s, rxd_r;
116
wire            start;
117
reg     [3:0]    rx_bit_cnt;
118
reg             rx_go;
119
reg     [9:0]    rxr;
120
reg             rx_valid, rx_valid_r;
121
wire            rx_we;
122
wire            rxf_full;
123
reg             rts_o;
124
reg             txf_empty_r;
125
reg             shift_en_r;
126
reg             rxd_r1, rxd_r2;
127
wire            lock_en;
128
reg             change;
129
reg             rx_sio_ce_d, rx_sio_ce_r1, rx_sio_ce_r2, rx_sio_ce;
130
reg     [1:0]    dpll_state, dpll_next_state;
131 5 rudi
reg     [5:0]    rxd_dly; //New input delay used to ensure no baud clocks
132
                        // occur twice in one baud period
133 2 rudi
///////////////////////////////////////////////////////////////////
134
//
135
// IO Fifo's
136
//
137
 
138
sasc_fifo4 tx_fifo(     .clk(           clk             ),
139
                        .rst(           rst             ),
140
                        .clr(           1'b0            ),
141
                        .din(           din_i           ),
142
                        .we(            we_i            ),
143
                        .dout(          txd_p           ),
144
                        .re(            load_e          ),
145
                        .full(          full_o          ),
146
                        .empty(         txf_empty       )
147
                        );
148
 
149
sasc_fifo4 rx_fifo(     .clk(           clk             ),
150
                        .rst(           rst             ),
151
                        .clr(           1'b0            ),
152
                        .din(           rxr[9:2]        ),
153
                        .we(            rx_we           ),
154
                        .dout(          dout_o          ),
155
                        .re(            re_i            ),
156
                        .full(          rxf_full        ),
157
                        .empty(         empty_o         )
158
                        );
159
 
160
///////////////////////////////////////////////////////////////////
161
//
162
// Transmit Logic
163
//
164
always @(posedge clk)
165
        if(!rst)        txf_empty_r <= #1 1'b1;
166
        else
167
        if(sio_ce)      txf_empty_r <= #1 txf_empty;
168
 
169
always @(posedge clk)
170
        load <= #1 !txf_empty_r & !shift_en & !cts_i;
171
 
172
always @(posedge clk)
173
        load_r <= #1 load;
174
 
175
assign load_e = load & sio_ce;
176
 
177
always @(posedge clk)
178
        if(load_e)              hold_reg <= #1 {STOP_BIT, txd_p, START_BIT};
179
        else
180
        if(shift_en & sio_ce)   hold_reg <= #1 {IDLE_BIT, hold_reg[9:1]};
181
 
182
always @(posedge clk)
183
        if(!rst)                                txd_o <= #1 IDLE_BIT;
184
        else
185
        if(sio_ce)
186
                if(shift_en | shift_en_r)       txd_o <= #1 hold_reg[0];
187
                else                            txd_o <= #1 IDLE_BIT;
188
 
189
always @(posedge clk)
190
        if(!rst)                tx_bit_cnt <= #1 4'h9;
191
        else
192
        if(load_e)              tx_bit_cnt <= #1 4'h0;
193
        else
194
        if(shift_en & sio_ce)   tx_bit_cnt <= #1 tx_bit_cnt + 4'h1;
195
 
196
always @(posedge clk)
197
        shift_en <= #1 (tx_bit_cnt != 4'h9);
198
 
199
always @(posedge clk)
200
        if(!rst)        shift_en_r <= #1 1'b0;
201
        else
202
        if(sio_ce)      shift_en_r <= #1 shift_en;
203
 
204
///////////////////////////////////////////////////////////////////
205
//
206
// Recieve Logic
207
//
208
 
209
always @(posedge clk)
210 5 rudi
begin
211
    rxd_dly[5:1] <= #1 rxd_dly[4:0];
212
         rxd_dly[0] <= #1rxd_i;
213
         rxd_s <= #1rxd_dly[5];  // rxd_s = delay 1
214
    rxd_r <= #1 rxd_s;  // rxd_r = delay 2       
215
end
216 2 rudi
 
217
 
218
assign start = (rxd_r == IDLE_BIT) & (rxd_s == START_BIT);
219
 
220
always @(posedge clk)
221
        if(!rst)                rx_bit_cnt <= #1 4'ha;
222
        else
223
        if(!rx_go & start)      rx_bit_cnt <= #1 4'h0;
224
        else
225
        if(rx_go & rx_sio_ce)   rx_bit_cnt <= #1 rx_bit_cnt + 4'h1;
226
 
227
always @(posedge clk)
228
        rx_go <= #1 (rx_bit_cnt != 4'ha);
229
 
230
always @(posedge clk)
231
        rx_valid <= #1 (rx_bit_cnt == 4'h9);
232
 
233
always @(posedge clk)
234
        rx_valid_r <= #1 rx_valid;
235
 
236
assign rx_we = !rx_valid_r & rx_valid & !rxf_full;
237
 
238
always @(posedge clk)
239
        if(rx_go & rx_sio_ce)   rxr <= {rxd_s, rxr[9:1]};
240
 
241
always @(posedge clk)
242
        rts_o <= #1 rxf_full;
243
 
244
///////////////////////////////////////////////////////////////////
245
//
246
// Reciever DPLL
247
//
248
 
249
// Uses 4x baud clock to lock to incoming stream
250
 
251
// Edge detector
252
always @(posedge clk)
253
        if(sio_ce_x4)   rxd_r1 <= #1 rxd_s;
254
 
255
always @(posedge clk)
256
        if(sio_ce_x4)   rxd_r2 <= #1 rxd_r1;
257
 
258
always @(posedge clk)
259 5 rudi
    if(!rst)
260
        change <= #1 1'b0;
261
    else if ((rxd_dly[1] != rxd_r1) || (rxd_dly[1] != rxd_s))
262
        change <= #1 1'b1;
263
    else if(sio_ce_x4)
264
        change <= #1 1'b0;
265 2 rudi
 
266
// DPLL FSM
267
always @(posedge clk or negedge rst)
268
        if(!rst)        dpll_state <= #1 2'h1;
269
        else
270
        if(sio_ce_x4)   dpll_state <= #1 dpll_next_state;
271
 
272
always @(dpll_state or change)
273
   begin
274
        rx_sio_ce_d = 1'b0;
275
        case(dpll_state)
276
           2'h0:
277
                if(change)      dpll_next_state = 3'h0;
278
                else            dpll_next_state = 3'h1;
279
           2'h1:begin
280
                rx_sio_ce_d = 1'b1;
281
                if(change)      dpll_next_state = 3'h3;
282
                else            dpll_next_state = 3'h2;
283
                end
284
           2'h2:
285
                if(change)      dpll_next_state = 3'h0;
286
                else            dpll_next_state = 3'h3;
287
           2'h3:
288
                if(change)      dpll_next_state = 3'h0;
289
                else            dpll_next_state = 3'h0;
290
        endcase
291
   end
292
 
293
// Compensate for sync registers at the input - allign sio 
294
// clock enable to be in the middle between two bit changes ...
295
always @(posedge clk)
296
        rx_sio_ce_r1 <= #1 rx_sio_ce_d;
297
 
298
always @(posedge clk)
299
        rx_sio_ce_r2 <= #1 rx_sio_ce_r1;
300
 
301
always @(posedge clk)
302
        rx_sio_ce <= #1 rx_sio_ce_r1 & !rx_sio_ce_r2;
303
 
304
endmodule
305
 
306
 

powered by: WebSVN 2.1.0

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