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

Subversion Repositories uart_observer

[/] [uart_observer/] [trunk/] [verilog/] [uart_receiver.v] - Blame information for rev 4

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

Line No. Rev Author Line
1 4 audriusa
module uart_receiver (
2
  input RXD,
3
  input CTR,
4
 
5
  input CLK_I,
6
 
7
  output wire [BITS-1:0] DAT_O
8
);
9
 
10
// Clock frequency Hz
11
 parameter CLOCK_FREQ = 90_000_000;
12
 
13
 // Serial port speed baud
14
 parameter BAUDS = 921600;
15
 
16
 parameter DIV_MAX = CLOCK_FREQ/BAUDS; // 9375; 781; 
17
 
18
 parameter BITS = 32;
19
 
20
 parameter N = 10; // 16;
21
 parameter H = N-1; // Highest bit
22
 
23
 // RAM buffer to transfer from
24
 parameter RAM_LENGTH = 8;
25
 reg [7:0] mem [RAM_LENGTH - 1:0];
26
 // RAM index of value currently being sent
27
 reg [7:0] ram_addr = 0;
28
 
29
 // Divider to 1 baud, receiver
30
 reg [BITS:0] divider_rx = 0;
31
 
32
 // Previous value of the RX line, for edge detection
33
 reg prev_rx = 1;
34
 
35
 // Internal phase counters to track what we are doing
36
 reg [4:0] phase_rx = 0;
37
 
38
 // Initialize RAM with content to send
39
 initial
40
   begin
41
     mem[0] <= 8'b0011_0000;
42
     mem[1] <= 8'b0011_0001;
43
     mem[2] <= 8'b0011_0010;
44
     mem[3] <= 8'b0011_0011;
45
     mem[4] <= 8'b0011_0100;
46
     mem[5] <= 8'b0011_0101;
47
     mem[6] <= 8'b0011_0110;
48
     mem[7] <= 8'b0011_0111;
49
   end
50
 
51
 // Increement the "phase_rx" variable that loops over 0-1-2-3-4-5-6-7-8-9-0
52
 task increment_phase_rx;
53
   begin
54
     if (phase_rx == 9)
55
       phase_rx = 0;
56
     else
57
       phase_rx = phase_rx + 1;
58
   end
59
 endtask;
60
 
61
 // Signal transmission edge (to FPGA)
62
 reg [7:0] rxEdge = 0;
63
 reg [7:0] rxData = 0;
64
 reg [2:0] rxBit = 0;
65
 
66
 // Receiver servicing loop
67
 always @(posedge CLK_I)
68
 begin
69
   if (RXD != prev_rx) // edge
70
   begin
71
     // Upon the edge, position relative point of reading into the middle 
72
     // of the data reference. This can be done at any edge but at least
73
     // will be done for the start bit edge. It is not much difference
74
     // if this is a positive edge or negative (both happen 1/2 baud interval
75
     // before the value that must be observed 
76
     divider_rx <= DIV_MAX  >> 2;
77
     prev_rx = RXD;
78
     rxEdge <= rxEdge + 1;
79
   end
80
   if (divider_rx > DIV_MAX)
81
     begin
82
       if (phase_rx == 0 && RXD == 0)
83
         begin
84
          // Start bit received         
85
           phase_rx <= 1;
86
           rxBit <= 0;
87
         end
88
       else if (phase_rx == 9 && RXD == 1)
89
         begin
90
           // stop bit received
91
           // rxData ready now
92
           phase_rx <= 0;
93
 
94
           // Take the received data into mem[0] for now.
95
           mem[0] <= rxData;
96
         end
97
       else if (phase_rx != 9 && phase_rx !=0)
98
         begin
99
           // Ordinary step
100
           rxData[rxBit] = RXD;
101
           rxBit = rxBit + 1;
102
           phase_rx <= phase_rx + 1;
103
         end;
104
       divider_rx = 0;
105
     end
106
 
107
   divider_rx = divider_rx + 1;
108
 end
109
 
110
 assign DAT_O[0] = rxData[0];
111
 assign DAT_O[1] = rxData[1];
112
 assign DAT_O[2] = rxData[2];
113
 assign DAT_O[3] = rxData[3];
114
 assign DAT_O[4] = rxData[4];
115
 assign DAT_O[5] = rxData[5];
116
 assign DAT_O[6] = rxData[6];
117
 assign DAT_O[7] = rxData[7];
118
 
119
endmodule

powered by: WebSVN 2.1.0

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