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

Subversion Repositories myblaze

[/] [myblaze/] [trunk/] [rtl/] [uart.py] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rockee
# -*- coding: utf-8 -*-
2
"""
3
    uart.py
4
    =======
5
 
6
    Simple 3-wire UART
7
 
8 5 rockee
    :copyright: Copyright (c) 2010 Jian Luo
9
    :author-email: jian.luo.cn(at_)gmail.com
10
    :license: LGPL, see LICENSE for details
11 2 rockee
    :revision: $Id: uart.py 5 2010-11-21 10:59:30Z rockee $
12
"""
13
 
14
from myhdl import *
15
 
16
#def BaudGen(enable16, reset, clock, freq_hz=50000000, baud=115200):
17
    #):
18
 
19
def UART(rx_data, rx_avail, rx_error, read_en,
20
         tx_data, tx_busy, write_en,
21
         uart_rxd, uart_txd, reset, clock,
22
         freq_hz=50000000, baud=115200):
23
    """
24
    Universal asynchronous receiver/transmitter
25
 
26
    rx_data:    receive data register output
27
    rx_avail:   receive data available output
28
    rx_error:   receive error output
29
    read_en:    read enable pulse input
30
    tx_data:    transmit data register input
31
    tx_busy:    transmitter busy output
32
    write_en:   write ebable pulse input
33
    uart_rxd:   receive physical wire input
34
    uart_txd:   transmit physical wire output
35
    reset:      synchronous uart reset input
36
    clock:      host clock input
37
    freq_hz:    host clock frequancy
38
    baud:       baud rate
39
    """
40
    divisor = freq_hz / baud / 16
41
    enable16_counter = Signal(intbv(0)[16:]) # outer timer loop
42
    enable16 = Signal(False)
43
 
44
    @always_comb
45
    def enable16_gen():
46
        enable16.next = not bool(enable16_counter)
47
 
48
    @always(clock.posedge)
49
    def enable16_tick():
50
        if reset or enable16:
51
            enable16_counter.next = divisor - 1
52
        else:
53
            enable16_counter.next = enable16_counter - 1
54
 
55
    tx_bitcount = Signal(intbv(0)[4:])
56
    tx_count16 = Signal(intbv(0)[4:])
57
    txd_reg = Signal(intbv(0)[9:])
58
    tx_is_busy = Signal(False) # internal busy status
59
 
60
    @always_comb
61
    def tx_busy_out():
62
        tx_busy.next = tx_is_busy
63
 
64
    @always(clock.posedge)
65
    def trans():
66
        if reset:
67
            tx_is_busy.next = False
68
            uart_txd.next = 1
69
            tx_count16.next = 0
70
        else:
71
            if write_en and not tx_is_busy:
72
                # Load tx data
73
                txd_reg.next = concat(tx_data[8:], False) # data & start bit '0'
74
                tx_bitcount.next = 10
75
                tx_count16.next = 0
76
                tx_is_busy.next = True
77
            if enable16:
78
                # ticking inner timer
79
                tx_count16.next = (tx_count16 + 1) % 16
80
 
81
                if tx_count16 == 0 and tx_is_busy:
82
                    tx_bitcount.next = tx_bitcount - 1
83
 
84
                    if tx_bitcount == 0:
85
                        # transmit finished
86
                        tx_is_busy.next = False
87
                    else:
88
                        uart_txd.next = txd_reg[0]
89
                        txd_reg.next = concat(True, txd_reg[9:1]) # stop bit '1' & data
90
 
91
    uart_rxd1 = Signal(False)
92
    uart_rxd2 = Signal(False)
93
    rx_bitcount = Signal(intbv(0)[4:])
94
    rx_count16 = Signal(intbv(0)[4:])
95
 
96
    rxd_reg = Signal(intbv(0)[8:])
97
    rx_is_busy = Signal(False)
98
 
99
    @always(clock.posedge)
100
    def rxd_sync():
101
        uart_rxd1.next = uart_rxd
102
        uart_rxd2.next = uart_rxd1
103
 
104
    @always(clock.posedge)
105
    def recv():
106
        if reset:
107
            rx_count16.next = 0
108
            rx_avail.next = False
109
            rx_error.next = False
110
            rx_is_busy.next = False
111
        else:
112
            if read_en:
113
                rx_avail.next = False
114
                rx_error.next = False
115
            if enable16:
116
                if not rx_is_busy:          # look for start bit
117
                    if not uart_rxd2:       # start bit found
118
                        rx_is_busy.next = True
119
                        rx_count16.next = 7 # sample in the middle of the data
120
                        rx_bitcount.next = 0
121
                else:
122
                    rx_count16.next = (rx_count16 + 1) % 16
123
 
124
                    if rx_count16 == 0:     # sample
125
                        rx_bitcount.next = (rx_bitcount + 1) % 16
126
 
127
                        if rx_bitcount == 0:
128
                            if uart_rxd2:   # start bit 
129
                                rx_is_busy.next = False # restart looking
130
                        elif rx_bitcount == 9:      # final check
131
                            rx_is_busy.next = False
132
                            if uart_rxd2:               # stop bit seems ok
133
                                rx_data.next = rxd_reg
134
                                rx_avail.next = True
135
                                rx_error.next = False
136
                            else:                       # not a stop bit
137
                                rx_error.next = True
138
                        else:
139
                            rxd_reg.next = concat(uart_rxd2, rxd_reg[8:1])
140
 
141
    return instances()
142
 
143
#from lut import ROM
144
from bram import *
145
from defines import *
146
from functions import *
147
 
148
filename_pattern = 'uarttest%s.vmem'
149
def prepare(size):
150
    src = open('core.py').read()
151
    STR = src.replace('\n','\r\n')
152
    bank = open(filename_pattern % '_one', 'w')
153
    banks = [open(filename_pattern % i, 'w') for i in range(4)]
154
    try:
155
        for i in range((2**size)):
156
            print >>banks[3-(i%4)], '%02x' % ord(STR[i%(len(STR))])
157
    finally:
158
        [f.close() for f in banks]
159
 
160
def prepare_one():
161
    STR = "%16s" % "Hello World!\r\n"
162
    bank = open(filename_pattern % '_one', 'w')
163
    for i, c in enumerate(STR):
164
        print >>bank, '%02x' % ord(c)
165
 
166
def uart_test_top(txd_line, rxd_line, debug_txd_line, debug_rxd_line, leds, reset, clock, size=4):
167
    rx_data = Signal(intbv(0)[32:])
168
    rx_avail = Signal(False)
169
    rx_error = Signal(False)
170
    read_en = Signal(False)
171
    tx_data = Signal(intbv(0)[32:])
172
    tx_busy = Signal(False)
173
    write_en = Signal(False)
174
    uart_rxd = Signal(False)
175
    uart_txd = Signal(False)
176
    addr = Signal(intbv(0)[size:])
177
    uart = UART(rx_data, rx_avail, rx_error, read_en,
178
           tx_data, tx_busy, write_en,
179
           uart_rxd, uart_txd, reset, clock,
180
           freq_hz=50000000, baud=38400)
181
    led_reg = Signal(intbv(0)[8:])
182
 
183
    bank_sel = Signal(intbv(0)[4:])
184
    data_out = Signal(intbv(0)[32:])
185
    #ram = BRAM(tx_data, rx_data, addr, read_en, write_en, clock, size=4,
186
                     #filename=filename_pattern % '_one')
187
    ram = BankedBRAM(data_out, rx_data, addr, bank_sel, write_en, clock,
188
                     size=size, to_verilog=True,
189
                     filename_pattern=filename_pattern)
190
    @always(clock.posedge)
191
    def say_hello():
192
        if reset:
193
            addr.next = 0
194
            debug_txd_line.next = False
195
            led_reg.next = 0b10101010
196
            write_en.next = False
197
            bank_sel.next = 0
198
            read_en.next = False
199
        else:
200
            debug_txd_line.next = uart_txd
201
            if not tx_busy:
202
                write_en.next = True
203
                tx_data.next = align_mem_load(data_out,
204
                                              transfer_size_type.WORD,
205
                                              addr)
206
            else:
207
                write_en.next = False
208
            if write_en and not tx_busy:
209
                addr.next = (addr +1) % (2**size)
210
                led_reg.next = ~led_reg
211
 
212
    @always_comb
213
    def led_out():
214
        leds.next = led_reg
215
        txd_line.next = debug_txd_line
216
 
217
    #@always(clock.posedge)
218
    #def echo():
219
        #if reset:
220
            #addr.next = 0
221
            #txd_line.next = False
222
            #led_reg.next = 0b10101010
223
            #write_en.next = False
224
            #read_en.next = True
225
            #uart_rxd.next = 1
226
        #else:
227
            #txd_line.next = uart_txd
228
            #uart_rxd.next = rxd_line
229
            #read_en.next = False
230
 
231
            #if rx_avail:
232
                #tx_data.next = rx_data
233
                #write_en.next = True
234
                #read_en.next = True
235
 
236
            #if write_en and not tx_busy:
237
                #write_en.next = False
238
                #led_reg.next = ~led_reg
239
 
240
    return instances()
241
 
242
import sys
243
from numpy import log2
244
 
245
if __name__ == '__main__':
246
    #rx_data = Signal(intbv(0)[8:])
247
    #rx_avail = Signal(False)
248
    #rx_error = Signal(False)
249
    #read_en = Signal(False)
250
    #tx_data = Signal(intbv(0)[8:])
251
    #tx_busy = Signal(False)
252
    #write_en = Signal(False)
253
    #uart_rxd = Signal(False)
254
    #uart_txd = Signal(False)
255
    #reset = Signal(False)
256
    #clock = Signal(False)
257
    #toVHDL(UART, rx_data, rx_avail, rx_error, read_en,
258
           #tx_data, tx_busy, write_en,
259
           #uart_rxd, uart_txd, reset, clock,
260
           #freq_hz=50000000, baud=115200)
261
    #toVerilog(UART, rx_data, rx_avail, rx_error, read_en,
262
           #tx_data, tx_busy, write_en,
263
           #uart_rxd, uart_txd, reset, clock,
264
           #freq_hz=50000000, baud=115200)
265
    size = int(log2(int(sys.argv[1]))) if len(sys.argv) > 1 else 4
266
    print 'size=%s' % size
267
    prepare(size)
268
    prepare_one()
269
    txd_line = Signal(False)
270
    rxd_line = Signal(False)
271
    debug_txd_line = Signal(False)
272
    debug_rxd_line = Signal(False)
273
    leds = Signal(intbv(0)[8:])
274
    reset = Signal(False)
275
    clock = Signal(False)
276
    #toVHDL(uart_test_top, debug_txd_line, debug_rxd_line, leds, reset, clock)
277
    toVerilog(uart_test_top, txd_line, rxd_line, debug_txd_line, debug_rxd_line, leds, reset, clock, size=size)
278
 
279
 
280
### EOF ###
281
# vim:smarttab:sts=4:ts=4:sw=4:et:ai:tw=80:
282
 

powered by: WebSVN 2.1.0

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