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

Subversion Repositories utosnet

[/] [utosnet/] [trunk/] [gateware/] [uTosNet_uart/] [uTosNet_uart.vhd] - Blame information for rev 2

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

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

powered by: WebSVN 2.1.0

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