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

Subversion Repositories a429_transmitter_receiver

[/] [a429_transmitter_receiver/] [trunk/] [rtl/] [a429_tx_iface.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 himar
 
2
////////////////////////////////////////////////////////////////////////////////
3
//
4
// Copyright (c) 2019 Himar Alonso
5
//
6
// Permission is hereby granted, free of charge, to any person obtaining a copy
7
// of this hardware, software, and associated documentation files
8
// (the "Product"), to deal in the Product without restriction, including
9
// without limitation the rights to use, copy, modify, merge, publish,
10
// distribute, sublicense, and/or sell copies of the Product, and to permit
11
// persons to whom the Product is furnished to do so, subject to the following
12
// conditions:
13
//
14
// The above copyright notice and this permission notice shall be included in
15
// all copies or substantial portions of the Product.
16
//
17
// THE PRODUCT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
// OUT OF OR IN CONNECTION WITH THE PRODUCT OR THE USE OR OTHER DEALINGS IN THE
23
// PRODUCT. 
24
//
25
////////////////////////////////////////////////////////////////////////////////
26
// A429 Transmitting Interface
27
// 
28
// Designed by Himar Alonso (himar@opencores.org)
29
// Date: 15/08/2019
30
////////////////////////////////////////////////////////////////////////////////
31
 
32
module a429_tx_iface
33
(
34
        input         clk2M,
35
        input         reset,
36
        input         enable,
37
        input   [1:0] speed,
38
        input         par_gen, // NOT implemented yet (data must include valid parity bit)
39
        input   [6:0] gap_bits,  // Values between 4 and 64
40
        input  [32:1] data,
41
        input         tx_req,
42
        output        a429_out_a,
43
        output        a429_out_b,
44
        output        ready
45
);
46
 
47
        //////////////////////////////////////////////////////
48
        // Generate clk429 according to the 'speed' setting //
49
        //////////////////////////////////////////////////////
50
        reg        clk429 = 1'b0;
51
        reg  [7:0] clk429_counter = 1'b0;
52
        wire [7:0] clk429_max_count  = (speed[0]) ? 8'd19 : 8'd159;
53
        wire [7:0] clk429_half_count = (speed[0]) ? 8'd10 : 8'd80;
54
 
55
        always @(posedge clk2M or posedge reset)
56
                if (reset)
57
                        clk429 <= 1'b0;
58
                else
59
                        clk429 <= (clk429_counter < clk429_half_count) ? 1'b1 : 1'b0;
60
 
61
        always @(posedge clk2M or posedge reset)
62
                if (reset)
63
                        clk429_counter <= 8'b0;
64
                else if (clk429_counter >= clk429_max_count)
65
                        clk429_counter <= 8'b0;
66
                else
67
                        clk429_counter <= clk429_counter + 8'b1;
68
 
69
 
70
        /////////////////////////////////////////////////////////////////////////
71
        // Format the output word by reversing the bits from the 'label' field //
72
        /////////////////////////////////////////////////////////////////////////
73
        wire [32:1]  a429_formatted_data = {data[32:9], data[1], data[2], data[3],
74
                data[4], data[5], data[6], data[7], data[8]};
75
 
76
        ////////////////////////
77
        // Output assignments //
78
        ////////////////////////
79
        // Generate a429_out_a and a429_out_b using RZ (return to zero) encoding
80
        // NOTE: Output is only active when transmitting data
81
        assign a429_out_a = (clk429 & (state == TRANSMITTING)) ? a429_out_a_bit : 1'b0;
82
        assign a429_out_b = (clk429 & (state == TRANSMITTING)) ? a429_out_b_bit : 1'b0;
83
        // Get output serial data from shif_reg's LSB
84
        wire a429_out_a_bit = shift_reg[1];
85
        wire a429_out_b_bit = ~shift_reg[1];
86
        // Ready to receive new data when state == IDLE
87
        assign ready = (state == IDLE);
88
 
89
        ///////////////////////////////////////////////
90
        // TX state machine parameters and registers //
91
        ///////////////////////////////////////////////
92
        localparam      IDLE         = 2'b00;
93
        localparam      TRANSMITTING = 2'b01;
94
        localparam      WAITING      = 2'b10;
95
 
96
        reg  [1:0] state;
97
        reg [32:1] shift_reg;
98
        reg  [4:0] shift_counter;
99
        reg  [6:0] gap_counter;
100
 
101
        /////////////////////////////////////
102
        // TX state machine implementation //
103
        /////////////////////////////////////
104
        always @(posedge clk429 or posedge reset)
105
                if (reset) begin
106
                        state <= IDLE;
107
                        shift_reg <= 32'b0;
108
                        shift_counter <= 5'b0;
109
                        gap_counter <= 6'b0;
110
                end else if (enable) begin
111
                        case (state)
112
                                IDLE:
113
                                        //
114
                                        // Wait for transmission request
115
                                        //
116
                                        if (tx_req == 1'b1) begin
117
                                                shift_reg <= a429_formatted_data;
118
                                                shift_counter <= 5'b11111;
119
                                                state <= TRANSMITTING;
120
                                        end
121
                                TRANSMITTING:
122
                                        //
123
                                        // Logical shift right until shift_counter = 0
124
                                        //
125
                                        begin
126
                                                shift_reg <= {shift_reg[1], shift_reg[32:2]};
127
                                                if (~|shift_counter) begin
128
                                                        // Substract state transition time (2 clock cycles)
129
                                                        // from total waiting time. The specification sets
130
                                                        // a minimum gap of 4 clock cycles and a maximum
131
                                                        // gap of 64 clock cycles between data words
132
                                                        if (gap_bits < 7'd4) // Minimum: 4
133
                                                                gap_counter <= 7'd2;
134
                                                        else if (gap_bits > 7'd64) // Maximum: 64
135
                                                                gap_counter <= 7'd62;
136
                                                        else
137
                                                                gap_counter <= gap_bits - 7'd2;
138
                                                        state <= WAITING;
139
                                                end else begin
140
                                                        shift_counter <= shift_counter - 5'b1;
141
                                                end
142
                                        end
143
                                WAITING:
144
                                        //
145
                                        // Wait specified time before fetching next ARINC 429 data word
146
                                        //
147
                                        if (~|gap_counter) // gap_counter == 0
148
                                                state <= IDLE;
149
                                        else
150
                                                gap_counter <= gap_counter - 7'b1;
151
                                default: // This should never happen
152
                                        state <= IDLE;
153
                        endcase
154
                end else begin // enable == 0
155
                        state <= IDLE;
156
                        shift_reg <= 32'b0;
157
                        shift_counter <= 5'b0;
158
                        gap_counter <= 6'b0;
159
                end
160
 
161
endmodule

powered by: WebSVN 2.1.0

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