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

Subversion Repositories utosnet

[/] [utosnet/] [trunk/] [gateware/] [uTosNet_example/] [uTosNet_controller/] [UTN_CTRL/] [uTosNet_uart.vhd] - Blame information for rev 10

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 sonicwave
----------------------------------------------------------------------------------
2
-- Company:             University of Southern Denmark
3
-- Engineer:            Simon Falsig
4
-- 
5
-- Create Date:         19/03/2010 
6
-- Design Name:         uTosNet
7
-- Module Name:         uTosNet_usb - Behavioral 
8
-- File Name:           uTosNet_uart.vhd
9
-- Project Name:        uTosNet
10
-- Target Devices:      SDU XC3S50AN Board
11
-- Tool versions:       Xilinx ISE 11.4
12
-- Description:         This module implements a very simple ASCII based protocol over
13
--                                      a uart. Data can be read and written from and to one port of a
14
--                                      dual-port blockRAM, where the other blockRAM port is available
15
--                                      to the user application. Communication takes place at the fol-
16
--                                      lowing settings:
17
--                                              Baudrate: 115200 kbps
18
--                                              Parity: none
19
--                                              Bits: 8 data bits, 1 stop bit
20
--                                              Flowcontrol: none
21
--                                      The protocol format can be seen in the documentation files.
22
--
23
--                                      Focus has mostly been on a simple implementation, as the 
24
--                                      module is to be used during courses at the university.
25
--
26
-- Dependencies:        The module uses the uart implementation from Ken Chapmans
27
--                                      PicoBlaze. More specifically the following files:
28
--                                              uart_rx.vhd
29
--                                              kcuart_rx.vhd
30
--                                              bbfifo_16x8.vhd
31
--                                              uart_tx.vhd
32
--                                              kcuart_tx.vhd
33
--                                      These files can be downloaded from Xilinx:
34
--                                      https://secure.xilinx.com/webreg/register.do?group=picoblaze
35
--
36
--                                      It should not be hard to implement the module using another
37
--                                      uart implementation though.
38
--
39
-- Revision: 
40
-- Revision 0.10 -      Initial release
41
--
42
-- Copyright 2010
43
--
44
-- This module is free software: you can redistribute it and/or modify
45
-- it under the terms of the GNU Lesser General Public License as published by
46
-- the Free Software Foundation, either version 3 of the License, or
47
-- (at your option) any later version.
48
--
49
-- This module is distributed in the hope that it will be useful,
50
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
51
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
52
-- GNU Lesser General Public License for more details.
53
--
54
-- You should have received a copy of the GNU Lesser General Public License
55
-- along with this module.  If not, see <http://www.gnu.org/licenses/>.
56
----------------------------------------------------------------------------------
57
 
58
library IEEE;
59
use IEEE.STD_LOGIC_1164.ALL;
60
use IEEE.STD_LOGIC_ARITH.ALL;
61
use IEEE.STD_LOGIC_UNSIGNED.ALL;
62
 
63
---- Uncomment the following library declaration if instantiating
64
---- any Xilinx primitives in this code.
65
--library UNISIM;
66
--use UNISIM.VComponents.all;
67
 
68
entity uTosNet_uart is
69
Port (  clk_50M                                         : in    STD_LOGIC;
70
                serial_out                                      : out   STD_LOGIC;
71
                serial_in                                       : in    STD_LOGIC;
72
                dataReg_addr                            : in    STD_LOGIC_VECTOR(5 downto 0);
73
                dataReg_dataIn                          : in    STD_LOGIC_VECTOR(31 downto 0);
74
                dataReg_dataOut                         : out   STD_LOGIC_VECTOR(31 downto 0);
75
                dataReg_clk                                     : in    STD_LOGIC;
76
                dataReg_writeEnable                     : in    STD_LOGIC);
77
end uTosNet_uart;
78
 
79
architecture Behavioral of uTosNet_uart is
80
 
81
        component dataRegister
82
        Port (  clka                                    : in    STD_LOGIC;
83
                        wea                                             : in    STD_LOGIC_VECTOR(0 downto 0);
84
                        addra                                   : in    STD_LOGIC_VECTOR(5 downto 0);
85
                        dina                                    : in    STD_LOGIC_VECTOR(31 downto 0);
86
                        douta                                   : out   STD_LOGIC_VECTOR(31 downto 0);
87
                        clkb                                    : in    STD_LOGIC;
88
                        web                                             : in    STD_LOGIC_VECTOR(0 downto 0);
89
                        addrb                                   : in    STD_LOGIC_VECTOR(5 downto 0);
90
                        dinb                                    : in    STD_LOGIC_VECTOR(31 downto 0);
91
                        doutb                                   : out   STD_LOGIC_VECTOR(31 downto 0));
92
        end component;
93
 
94
        component uart_rx
95
        Port (  serial_in                               : in    STD_LOGIC;
96
                        data_out                                : out   STD_LOGIC_VECTOR(7 downto 0);
97
                        read_buffer                             : in    STD_LOGIC;
98
                        reset_buffer                    : in    STD_LOGIC;
99
                        en_16_x_baud                    : in    STD_LOGIC;
100
                        buffer_data_present             : out   STD_LOGIC;
101
                        buffer_full                             : out   STD_LOGIC;
102
                        buffer_half_full                : out   STD_LOGIC;
103
                        clk                                             : in    STD_LOGIC);
104
        end component;
105
 
106
        component uart_tx
107
        Port (  serial_out                              : out   STD_LOGIC;
108
                        data_in                                 : in    STD_LOGIC_VECTOR(7 downto 0);
109
                        write_buffer                    : in    STD_LOGIC;
110
                        reset_buffer                    : in    STD_LOGIC;
111
                        en_16_x_baud                    : in    STD_LOGIC;
112
                        buffer_full                             : out   STD_LOGIC;
113
                        buffer_half_full                : out   STD_LOGIC;
114
                        clk                                             : in    STD_LOGIC);
115
        end component;
116
 
117
        signal baudCount                                : integer range 0 to 36 :=0;
118
        signal en_16_x_baud                             : STD_LOGIC;
119
        signal readFromUart                             : STD_LOGIC;
120
        signal rxData                                   : STD_LOGIC_VECTOR(7 downto 0);
121
        signal rxDataPresent                    : STD_LOGIC;
122
        signal rxFull                                   : STD_LOGIC;
123
        signal rxHalfFull                               : STD_LOGIC;
124
 
125
        signal txData                                   : STD_LOGIC_VECTOR(7 downto 0);
126
        signal writeToUart                              : STD_LOGIC;
127
        signal txFull                                   : STD_LOGIC;
128
        signal txHalfFull                               : STD_LOGIC;
129
 
130
        constant UARTDIV                                : STD_LOGIC_VECTOR(5 downto 0) := "011010";
131
 
132
        type STATES is (IDLE, COMMAND_IN, WAIT1, REG_IN, WAIT2, INDEX_IN, WAIT3, SPACE_IN, WAIT4, DATA_IN, WAIT_DATA_IN, DATA_OUT, PERFORM_READ_SETUP, PERFORM_READ_CLK, PERFORM_READ_DONE, PERFORM_WRITE_SETUP, PERFORM_WRITE_CLK, PERFORM_WRITE_DONE);
133
 
134
        signal state                                    : STATES := IDLE;
135
        signal nextState                                : STATES := IDLE;
136
 
137
        type COMMANDS is (CMD_NONE, CMD_READ, CMD_WRITE, CMD_COMMIT_READ, CMD_COMMIT_WRITE);
138
 
139
        signal currentCommand                   : COMMANDS := CMD_NONE;
140
 
141
        signal int_dataReg_dataIn               : STD_LOGIC_VECTOR(31 downto 0);
142
        signal int_dataReg_addr                 : STD_LOGIC_VECTOR(5 downto 0);
143
        signal int_dataReg_dataOut              : STD_LOGIC_VECTOR(31 downto 0);
144
        signal int_dataReg_we                   : STD_LOGIC_VECTOR(0 downto 0);
145
        signal int_dataReg_clk                  : STD_LOGIC;
146
 
147
        signal dataReg_writeEnable_V    : STD_LOGIC_VECTOR(0 downto 0);
148
 
149
        signal inputBuffer                              : STD_LOGIC_VECTOR(31 downto 0) := (others => '0');
150
        signal outputBuffer                             : STD_LOGIC_VECTOR(31 downto 0) := (others => '1');
151
 
152
        signal readCounter                              : STD_LOGIC_VECTOR(3 downto 0) := (others => '0');
153
        signal writeCounter                             : STD_LOGIC_VECTOR(3 downto 0) := (others => '0');
154
 
155
        signal currentReg                               : STD_LOGIC_VECTOR(2 downto 0) := (others => '0');
156
        signal currentIndex                             : STD_LOGIC_VECTOR(2 downto 0) := (others => '0');
157
 
158
        signal commitRead                               : STD_LOGIC := '0';
159
        signal commitWrite                              : STD_LOGIC := '0';
160
 
161
begin
162
 
163
        dataReg_writeEnable_V(0) <= dataReg_writeEnable;                                                 --Conversion from std_logic to std_logic_vector(0 downto 0) - to allow for dataReg_writeEnable to be a std_logic, which is nicer...:)
164
 
165
        dataRegisterInst : dataRegister                                                                                         --Instantation of the dual-port blockram used for the dataregister
166
        Port map (      clka => dataReg_clk,                                                                                    --PortA is used for the user application
167
                                wea => dataReg_writeEnable_V,                                                                   --
168
                                addra => dataReg_addr,                                                                                  --
169
                                dina => dataReg_dataIn,                                                                                 --
170
                                douta => dataReg_dataOut,                                                                               --
171
                                clkb => int_dataReg_clk,                                                                                --PortB is used for the SPI interface
172
                                web => int_dataReg_we,                                                                                  --
173
                                addrb => int_dataReg_addr,                                                                              --
174
                                dinb => int_dataReg_dataIn,                                                                             --
175
                                doutb => int_dataReg_dataOut);                                                                  --
176
 
177
        rx_inst: uart_rx
178
        Port map (      serial_in => serial_in,
179
                                data_out => rxData,
180
                                read_buffer => readFromUart,
181
                                reset_buffer => '0',
182
                                en_16_x_baud => en_16_x_baud,
183
                                buffer_data_present => rxDataPresent,
184
                                buffer_full => rxFull,
185
                                buffer_half_full => rxHalfFull,
186
                                clk => clk_50M );
187
 
188
        tx_inst : uart_tx
189
        Port map (      serial_out => serial_out,
190
                                data_in => txData,
191
                                write_buffer => writeToUart,
192
                                reset_buffer => '0',
193
                                en_16_x_baud => en_16_x_baud,
194
                                buffer_full => txFull,
195
                                buffer_half_full => txHalfFull,
196
                                clk => clk_50M);
197
 
198
        baudTimer_inst: process(clk_50M)
199
        begin
200
                if(clk_50M'event and clk_50M='1')then
201
                        if(baudCount = UARTDIV)then
202
                                baudCount <= 0;
203
                                en_16_x_baud <= '1';
204
                        else
205
                                baudCount <= baudCount + 1;
206
                                en_16_x_baud <= '0';
207
                        end if;
208
                end if;
209
        end process baudTimer_inst;
210
 
211
 
212
        process(clk_50M)
213
        begin
214
                if(clk_50M = '1' and clk_50M'event) then
215
                        state <= nextState;
216
 
217
                        readFromUart <= '0';
218
                        writeToUart <= '0';
219
 
220
                        case state is
221
                                when IDLE =>
222
                                        currentCommand <= CMD_NONE;
223
                                        readCounter <= (others => '0');
224
                                        writeCounter <= (others => '0');
225
                                        commitRead <= '0';
226
                                        commitWrite <= '0';
227
                                when COMMAND_IN =>
228
                                        commitRead <= '0';
229
                                        commitWrite <= '0';
230
                                        if(rxDataPresent = '1') then
231
                                                case rxData is
232
                                                        when "01110010" => --'r'
233
                                                                currentCommand <= CMD_READ;
234
                                                        when "01110111" => --'w'
235
                                                                currentCommand <= CMD_WRITE;
236
                                                        when "01110100" => --'t'
237
                                                                commitRead <= '1';                                      --Might need to switch with write
238
                                                                currentCommand <= CMD_NONE;
239
                                                        when "01100011" => --'c'
240
                                                                commitWrite <= '1';                                     --Might need to switch with read
241
                                                                currentCommand <= CMD_NONE;
242
                                                        when others =>
243
                                                                currentCommand <= CMD_NONE;
244
                                                end case;
245
                                                readFromUart <= '1';
246
                                        end if;
247
                                when WAIT1 =>
248
                                when REG_IN =>
249
                                        if(rxDataPresent = '1') then
250
                                                case rxData is
251
                                                        when "00110000" =>
252
                                                                currentReg <= "000";
253
                                                        when "00110001" =>
254
                                                                currentReg <= "001";
255
                                                        when "00110010" =>
256
                                                                currentReg <= "010";
257
                                                        when "00110011" =>
258
                                                                currentReg <= "011";
259
                                                        when "00110100" =>
260
                                                                currentReg <= "100";
261
                                                        when "00110101" =>
262
                                                                currentReg <= "101";
263
                                                        when "00110110" =>
264
                                                                currentReg <= "110";
265
                                                        when "00110111" =>
266
                                                                currentReg <= "111";
267
                                                        when others =>
268
                                                                currentCommand <= CMD_NONE;
269
                                                end case;
270
                                                readFromUart <= '1';
271
                                        end if;
272
                                when WAIT2 =>
273
                                when INDEX_IN =>
274
                                        if(rxDataPresent = '1') then
275
                                                case rxData is
276
                                                        when "00110000" =>
277
                                                                currentIndex <= "000";
278
                                                        when "00110001" =>
279
                                                                currentIndex <= "001";
280
                                                        when "00110010" =>
281
                                                                currentIndex <= "010";
282
                                                        when "00110011" =>
283
                                                                currentIndex <= "011";
284
                                                        when "00110100" =>
285
                                                                currentIndex <= "100";
286
                                                        when "00110101" =>
287
                                                                currentIndex <= "101";
288
                                                        when "00110110" =>
289
                                                                currentIndex <= "110";
290
                                                        when "00110111" =>
291
                                                                currentIndex <= "111";
292
                                                        when others =>
293
                                                                currentCommand <= CMD_NONE;
294
                                                end case;
295
                                                readFromUart <= '1';
296
                                        end if;
297
                                when WAIT3 =>
298
                                when SPACE_IN =>
299
                                        if(rxDataPresent = '1') then
300
                                                if(not(rxData = "00100000")) then
301
                                                        currentCommand <= CMD_NONE;
302
                                                end if;
303
                                                readFromUart <= '1';
304
                                        end if;
305
                                when WAIT4 =>
306
                                when DATA_IN =>
307
                                        if(rxDataPresent = '1') then
308
                                                case rxData is
309
                                                        when "00110000" =>      --'0'
310
                                                                inputBuffer <= inputBuffer(27 downto 0) & "0000";
311
                                                        when "00110001" =>      --'1'
312
                                                                inputBuffer <= inputBuffer(27 downto 0) & "0001";
313
                                                        when "00110010" =>      --'2'
314
                                                                inputBuffer <= inputBuffer(27 downto 0) & "0010";
315
                                                        when "00110011" =>      --'3'
316
                                                                inputBuffer <= inputBuffer(27 downto 0) & "0011";
317
                                                        when "00110100" =>      --'4'
318
                                                                inputBuffer <= inputBuffer(27 downto 0) & "0100";
319
                                                        when "00110101" =>      --'5'
320
                                                                inputBuffer <= inputBuffer(27 downto 0) & "0101";
321
                                                        when "00110110" =>      --'6'
322
                                                                inputBuffer <= inputBuffer(27 downto 0) & "0110";
323
                                                        when "00110111" =>      --'7'
324
                                                                inputBuffer <= inputBuffer(27 downto 0) & "0111";
325
                                                        when "00111000" =>      --'8'
326
                                                                inputBuffer <= inputBuffer(27 downto 0) & "1000";
327
                                                        when "00111001" =>      --'9'
328
                                                                inputBuffer <= inputBuffer(27 downto 0) & "1001";
329
                                                        when "01100001" =>      --'a'
330
                                                                inputBuffer <= inputBuffer(27 downto 0) & "1010";
331
                                                        when "01100010" =>      --'b'
332
                                                                inputBuffer <= inputBuffer(27 downto 0) & "1011";
333
                                                        when "01100011" =>      --'c'
334
                                                                inputBuffer <= inputBuffer(27 downto 0) & "1100";
335
                                                        when "01100100" =>      --'d'
336
                                                                inputBuffer <= inputBuffer(27 downto 0) & "1101";
337
                                                        when "01100101" =>      --'e'
338
                                                                inputBuffer <= inputBuffer(27 downto 0) & "1110";
339
                                                        when "01100110" =>      --'f'
340
                                                                inputBuffer <= inputBuffer(27 downto 0) & "1111";
341
                                                        when others =>
342
                                                                currentCommand <= CMD_NONE;
343
                                                end case;
344
                                                readFromUart <= '1';
345
                                                readCounter <= readCounter + 1;
346
                                        end if;
347
                                when WAIT_DATA_IN =>
348
                                when DATA_OUT =>
349
                                        writeToUart <= '1';
350
                                        if(writeCounter = 8) then
351
                                                txData <= "00100000";   --Transmit a space to make thinks look nicer...:)
352
                                        else
353
                                                case outputBuffer(31 downto 28) is
354
                                                        when "0000" =>  --'0'
355
                                                                txData <= "00110000";
356
                                                        when "0001" =>  --'1'
357
                                                                txData <= "00110001";
358
                                                        when "0010" =>  --'2'
359
                                                                txData <= "00110010";
360
                                                        when "0011" =>  --'3'
361
                                                                txData <= "00110011";
362
                                                        when "0100" =>  --'4'
363
                                                                txData <= "00110100";
364
                                                        when "0101" =>  --'5'
365
                                                                txData <= "00110101";
366
                                                        when "0110" =>  --'6'
367
                                                                txData <= "00110110";
368
                                                        when "0111" =>  --'7'
369
                                                                txData <= "00110111";
370
                                                        when "1000" =>  --'8'
371
                                                                txData <= "00111000";
372
                                                        when "1001" =>  --'9'
373
                                                                txData <= "00111001";
374
                                                        when "1010" =>  --'a'
375
                                                                txData <= "01100001";
376
                                                        when "1011" =>  --'b'
377
                                                                txData <= "01100010";
378
                                                        when "1100" =>  --'c'
379
                                                                txData <= "01100011";
380
                                                        when "1101" =>  --'d'
381
                                                                txData <= "01100100";
382
                                                        when "1110" =>  --'e'
383
                                                                txData <= "01100101";
384
                                                        when "1111" =>  --'f'
385
                                                                txData <= "01100110";
386
                                                        when others =>
387
                                                end case;
388
                                        end if;
389
                                        outputBuffer <= outputBuffer(27 downto 0) & "0000";
390
                                        writeCounter <= writeCounter + 1;
391
                                when PERFORM_READ_SETUP =>
392
                                        int_dataReg_addr <= currentReg & currentIndex;
393
                                        int_dataReg_we <= "0";
394
                                        int_dataReg_clk <= '0';
395
                                when PERFORM_READ_CLK =>
396
                                        int_dataReg_clk <= '1';
397
                                when PERFORM_READ_DONE =>
398
                                        outputBuffer <= int_dataReg_dataOut;
399
                                        int_dataReg_clk <= '0';
400
                                when PERFORM_WRITE_SETUP =>
401
                                        int_dataReg_addr <= currentReg & currentIndex;
402
                                        int_dataReg_dataIn <= inputBuffer;
403
                                        int_dataReg_we <= "1";
404
                                        int_dataReg_clk <= '0';
405
                                when PERFORM_WRITE_CLK =>
406
                                        int_dataReg_clk <= '1';
407
                                when PERFORM_WRITE_DONE =>
408
                                        int_dataReg_we <= "0";
409
                                        int_dataReg_clk <= '0';
410
                        end case;
411
                end if;
412
        end process;
413
 
414
        process(state, rxDataPresent, currentCommand, readCounter, writeCounter)
415
        begin
416
                if((currentCommand = CMD_NONE) and not ((state = COMMAND_IN) or (state = IDLE))) then
417
                        nextState <= IDLE;
418
                else
419
                        case state is
420
                                when IDLE =>
421
                                        nextState <= COMMAND_IN;
422
                                when COMMAND_IN =>
423
                                        if(rxDataPresent = '1') then
424
                                                nextState <= WAIT1;
425
                                        else
426
                                                nextState <= COMMAND_IN;
427
                                        end if;
428
                                when WAIT1 =>
429
                                        if(rxDataPresent = '0') then
430
                                                nextState <= REG_IN;
431
                                        else
432
                                                nextState <= WAIT1;
433
                                        end if;
434
                                when REG_IN =>
435
                                        if(rxDataPresent = '1') then
436
                                                nextState <= WAIT2;
437
                                        else
438
                                                nextState <= REG_IN;
439
                                        end if;
440
                                when WAIT2 =>
441
                                        if(rxDataPresent = '0') then
442
                                                nextState <= INDEX_IN;
443
                                        else
444
                                                nextState <= WAIT2;
445
                                        end if;
446
                                when INDEX_IN =>
447
                                        if(rxDataPresent = '1') then
448
                                                nextState <= WAIT3;
449
                                        else
450
                                                nextState <= INDEX_IN;
451
                                        end if;
452
                                when WAIT3 =>
453
                                        if(rxDataPresent = '0') then
454
                                                if(currentCommand = CMD_READ) then
455
                                                        nextState <= PERFORM_READ_SETUP;
456
                                                else
457
                                                        nextState <= SPACE_IN;
458
                                                end if;
459
                                        else
460
                                                nextState <= WAIT3;
461
                                        end if;
462
                                when SPACE_IN =>
463
                                        if(rxDataPresent = '1') then
464
                                                nextState <= WAIT4;
465
                                        else
466
                                                nextState <= SPACE_IN;
467
                                        end if;
468
                                when WAIT4 =>
469
                                        if(rxDataPresent = '0') then
470
                                                nextState <= DATA_IN;
471
                                        else
472
                                                nextState <= WAIT4;
473
                                        end if;
474
                                when DATA_IN =>
475
                                        if(rxDataPresent = '1') then
476
                                                nextState <= WAIT_DATA_IN;
477
                                        else
478
                                                nextState <= DATA_IN;
479
                                        end if;
480
                                when WAIT_DATA_IN =>
481
                                        if(rxDataPresent = '0') then
482
                                                if(readCounter = 8) then
483
                                                        nextState <= PERFORM_WRITE_SETUP;
484
                                                else
485
                                                        nextState <= DATA_IN;
486
                                                end if;
487
                                        else
488
                                                nextState <= WAIT_DATA_IN;
489
                                        end if;
490
                                when DATA_OUT =>
491
                                        if(writeCounter = 8) then
492
                                                nextState <= IDLE;
493
                                        else
494
                                                nextState <= DATA_OUT;
495
                                        end if;
496
                                when PERFORM_READ_SETUP =>
497
                                        nextState <= PERFORM_READ_CLK;
498
                                when PERFORM_READ_CLK =>
499
                                        nextState <= PERFORM_READ_DONE;
500
                                when PERFORM_READ_DONE =>
501
                                        nextState <= DATA_OUT;
502
                                when PERFORM_WRITE_SETUP =>
503
                                        nextState <= PERFORM_WRITE_CLK;
504
                                when PERFORM_WRITE_CLK =>
505
                                        nextState <= PERFORM_WRITE_DONE;
506
                                when PERFORM_WRITE_DONE =>
507
                                        nextState <= IDLE;
508
                        end case;
509
                end if;
510
        end process;
511
 
512
end Behavioral;
513
 

powered by: WebSVN 2.1.0

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