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

Subversion Repositories uart2bus

[/] [uart2bus/] [trunk/] [verilog/] [bench/] [uart_tasks.v] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 motilito
//------------------------------------------------------------------------------
2
// uart tasks:
3
//              send_serial             serial transmitter 
4
//              get_serial              serial receiver 
5
//
6
//------------------------------------------------------------------------------
7
 
8
/*  Serial Parameters used for send_serial task and its callers. */
9
`define PARITY_OFF              1'b0
10
`define PARITY_ON               1'b1
11
`define PARITY_ODD              1'b0
12
`define PARITY_EVEN             1'b1
13
`define NSTOPS_1                1'b0
14
`define NSTOPS_2                1'b1
15
`define BAUD_115200             3'b000
16
`define BAUD_38400              3'b001
17
`define BAUD_28800              3'b010
18
`define BAUD_19200              3'b011
19
`define BAUD_9600               3'b100
20
`define BAUD_4800               3'b101
21
`define BAUD_2400               3'b110
22
`define BAUD_1200               3'b111
23
`define NBITS_7                 1'b0
24
`define NBITS_8                 1'b1
25
// constants for status from get_serial task 
26
`define RECEIVE_RESULT_OK                       4'b1000
27
`define RECEIVE_RESULT_FALSESTART       4'b0001
28
`define RECEIVE_RESULT_BADPARITY        4'b0010
29
`define RECEIVE_RESULT_BADSTOP          4'b0100
30
 
31
// uart tasks global interfaces signals 
32
reg serial_out;         // transmit serial output 
33
reg serial_in;          // receive serial input 
34
reg [7:0] get_serial_data;               // data received from serial 
35
reg [7:0] get_serial_status;     // status of receive operation 
36
 
37
//------------------------------------------------------------------------------
38
// uart transmit task 
39
// 
40
// usage:
41
//              send_serial (data, baud_rate, parity_type, parity_on, stop_bits_num, 
42
//                                                                                                              data_bit_num, baud_error);
43
// where:
44
//              data                    data character for transmission 
45
//              parity_type             this is a flag indicating that parity should be even 
46
//                                              (either 'PARITY_ODD or 'PARITY_EVEN)
47
//              parity_on               indicates that the parity is used 
48
//                                              (either 'PARITY_OFF or 'PARITY_ON)
49
//              stop_bits_num   number of stop bits (either NSTOPS_1 or NSTOPS_2)
50
//              data_bit_num    number of data bits (either NBITS_7 or NBITS_8)
51
//              baud_error              baud error in precentage (-5 is -5%)
52
// 
53
 
54
task send_serial;
55
// task input parameters 
56
input [7:0] inputchar;
57
input baud;
58
input paritytype;
59
input parityenable;
60
input nstops;
61
input nbits;
62
input baud_error_factor;
63
// internal registers 
64
reg       nbits;
65
reg       parityenable;
66
reg       paritytype;
67
reg [1:0] baud;
68
reg       nstops;
69
integer         baud_error_factor;  // e.g. +5 means 5% too fast and -5 means 5% too slow
70
reg     [7:0]    char;
71
reg [7:0]        disp_char;
72
reg         parity_bit;
73
integer     bit_time;
74
integer         num_of_bits;
75
// task implementation 
76
begin
77
        char = inputchar;
78
        parity_bit = 1'b0;
79
        // calculate bit time from input baud rate - this assumes a simulation resolution of 1ns 
80
        case (baud)
81
                `BAUD_115200: bit_time = 1000000000/(115200 + 1152*baud_error_factor);
82
//              `BAUD_115200: bit_time = 40000000000/(115200 + 1152*baud_error_factor);
83
                `BAUD_38400:  bit_time = 1000000000/(38400 + 384*baud_error_factor);
84
                `BAUD_28800:  bit_time = 1000000000/(28800 + 288*baud_error_factor);
85
                `BAUD_19200:  bit_time = 1000000000/(19200 + 192*baud_error_factor);
86
                `BAUD_9600:   bit_time = 1000000000/(9600 + 96*baud_error_factor);
87
                `BAUD_4800:   bit_time = 1000000000/(4800 + 48*baud_error_factor);
88
                `BAUD_2400:   bit_time = 1000000000/(2400 + 24*baud_error_factor);
89
                `BAUD_1200:   bit_time = 1000000000/(1200 + 12*baud_error_factor);
90
        endcase
91
 
92
        // display info 
93
        disp_char = (char >= 8'h20) ? char : 8'hb0;
94
        $display ("Sending character 0x%h (\"%c\"), at %0d baud (err=%0d), %0d bits, %0s parity, %0d stops",
95
                (nbits == `NBITS_7) ? (char & 8'h7f) : char,
96
                (nbits == `NBITS_7) ? (disp_char & 8'h7f) : disp_char,
97
                1000000000/bit_time,
98
                baud_error_factor,
99
                (nbits == `NBITS_7) ? 7 : 8,
100
                (parityenable == `PARITY_OFF) ? "NONE" : (paritytype == `PARITY_EVEN) ? "EVEN" : "ODD",
101
                (nstops == `NSTOPS_1) ? 1 : 2
102
        );
103
 
104
        // Start bit
105
        serial_out = 1'b0;   // Start bit.
106
        #(bit_time);
107
 
108
        // Output data bits
109
        num_of_bits = (nbits == `NBITS_7) ? 7 : 8;
110
        repeat (num_of_bits)
111
        begin
112
                serial_out = char[0];
113
                #(bit_time);
114
                char = {1'b0, char[7:1]};
115
        end
116
 
117
        // check if parity is enabled 
118
        if (parityenable == `PARITY_ON) begin
119
                parity_bit = (nbits == `NBITS_7) ? ^inputchar[6:0] : ^inputchar[7:0];
120
                // even parity
121
                if (paritytype == `PARITY_ODD)
122
                        parity_bit = ~parity_bit;
123
 
124
                serial_out = parity_bit;
125
                #(bit_time);
126
        end
127
 
128
        // Stop bit.
129
        serial_out = 1'b1;
130
        #(bit_time);
131
        // Second stop bit
132
        if (nstops)
133
                #(bit_time);
134
end
135
endtask
136
 
137
//------------------------------------------------------------------------------
138
// uart receive task 
139
// 
140
// usage:
141
//              get_serial (baud_rate, parity_type, parity_on, stop_bits_num, data_bit_num);
142
// where:
143
//              data                    data character for transmission 
144
//              parity_type             this is a flag indicating that parity should be even 
145
//                                              (either 'PARITY_ODD or 'PARITY_EVEN)
146
//              parity_on               indicates that the parity is used 
147
//                                              (either 'PARITY_OFF or 'PARITY_ON)
148
//              stop_bits_num   number of stop bits (either NSTOPS_1 or NSTOPS_2)
149
//              data_bit_num    number of data bits (either NBITS_7 or NBITS_8)
150
// 
151
task get_serial;
152
// input parameters 
153
input baud;
154
input paritytype;
155
input parityenable;
156
input nstops;
157
input nbits;
158
// internal registers 
159
reg       nbits;
160
reg       parityenable;
161
reg       paritytype;
162
reg [1:0] baud;
163
reg       nstops;
164
integer     bit_time;
165
reg         expected_parity;
166
integer         num_of_bits;
167
// task implementation 
168
begin
169
        // init receive globals 
170
        get_serial_status = 0;
171
        get_serial_data = 0;
172
 
173
        // calculate bit time from input baud rate - this assumes a simulation resolution of 1ns 
174
        case (baud)
175
                `BAUD_115200: bit_time = 1000000000/115200;
176
                `BAUD_38400:  bit_time = 1000000000/38400;
177
                `BAUD_28800:  bit_time = 1000000000/28800;
178
                `BAUD_19200:  bit_time = 1000000000/19200;
179
                `BAUD_9600:   bit_time = 1000000000/9600;
180
                `BAUD_4800:   bit_time = 1000000000/4800;
181
                `BAUD_2400:   bit_time = 1000000000/2400;
182
                `BAUD_1200:   bit_time = 1000000000/1200;
183
        endcase
184
 
185
        // Assume OK until bad things happen.
186
        get_serial_status = `RECEIVE_RESULT_OK;
187
 
188
        // wait for start bit edge 
189
        @(negedge serial_in);
190
 
191
        // wait till center of start bit 
192
        #(bit_time/2);
193
 
194
        // make sure its really a start bit
195
        if (serial_in != 0)
196
                get_serial_status = get_serial_status | `RECEIVE_RESULT_FALSESTART;
197
        else
198
        begin
199
                // get all the data bits (7 or 8) 
200
                num_of_bits = (nbits == `NBITS_7) ? 7 : 8;
201
                repeat (num_of_bits)
202
                begin
203
                        // wait till center 
204
                        #(bit_time);
205
                        // sample a data bit
206
                        get_serial_data = {serial_in, get_serial_data[7:1]};
207
                end
208
 
209
                // If we are only expecting 7 bits, go ahead and right-justify what we have
210
                if (nbits == `NBITS_7)
211
                        get_serial_data = {1'b0, get_serial_data[7:1]};
212
 
213
                // wait for next bit to start 
214
                #(bit_time);
215
 
216
                // now, we have either a parity bit, or a stop bit
217
                if (parityenable == `PARITY_ON) begin
218
                        if (paritytype == `PARITY_EVEN)
219
                                expected_parity = (nbits == `NBITS_7) ? (^get_serial_data[6:0]) :
220
                                                                                                                        (^get_serial_data[7:0]);
221
                        else
222
                                expected_parity = (nbits == `NBITS_7) ? (~(^get_serial_data[6:0])) :
223
                                                                                                                        (~(^get_serial_data[7:0]));
224
 
225
                        if (expected_parity != serial_in)
226
                                get_serial_status = get_serial_status | `RECEIVE_RESULT_BADPARITY;
227
                end
228
                // wait for either 1 or 2 stop bits
229
                else begin
230
                        // this is a stop bit.
231
                        if (serial_in != 1)
232
                                get_serial_status = get_serial_status | `RECEIVE_RESULT_BADSTOP;
233
                        else
234
                                // that was cool.  if 2 stops, then do this again
235
                                if (nstops)
236
                                begin
237
                                        #(bit_time);
238
                                        if (serial_in != 1)
239
                                                get_serial_status = get_serial_status | `RECEIVE_RESULT_BADSTOP;
240
                                end
241
                        #(bit_time/2);
242
                end
243
        end
244
end
245
endtask
246
 

powered by: WebSVN 2.1.0

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