Infrared working
[mw/milkymist.git] / cores / rc5 / rtl / rc5.v
1 /*
2  * Milkymist VJ SoC
3  * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
4  * Copyright (C) 2007 Das Labor
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, version 3 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 module rc5 #(
20         parameter csr_addr = 4'h0,
21         parameter clk_freq = 100000000
22 ) (
23         input sys_clk,
24         input sys_rst,
25
26         input [13:0] csr_a,
27         input csr_we,
28         input [31:0] csr_di,
29         output reg [31:0] csr_do,
30
31         output reg rx_irq,
32
33         input rx
34 );
35
36 //-----------------------------------------------------------------
37 // enable16 generator
38 //-----------------------------------------------------------------
39 parameter divisor = clk_freq/570/16;
40
41 reg [15:0] enable16_counter;
42
43 wire enable16;
44 assign enable16 = (enable16_counter == 16'd0);
45
46 always @(posedge sys_clk) begin
47         if(sys_rst)
48                 enable16_counter <= divisor - 1;
49         else begin
50                 enable16_counter <= enable16_counter - 16'd1;
51                 if(enable16)
52                         enable16_counter <= divisor - 1;
53         end
54 end
55
56 //-----------------------------------------------------------------
57 // Synchronize rx
58 //-----------------------------------------------------------------
59 reg rx1;
60 reg rx2;
61
62 always @(posedge sys_clk) begin
63         rx1 <= rx;
64         rx2 <= rx1;
65 end
66
67 //-----------------------------------------------------------------
68 // RX Logic
69 //-----------------------------------------------------------------
70 reg rx_busy;
71 reg [3:0] rx_count16;
72 reg [3:0] rx_bitcount;
73 reg [12:0] rx_reg;
74 reg [12:0] rx_data;
75
76 always @(posedge sys_clk) begin
77         if(sys_rst) begin
78                 rx_irq <= 1'b0;
79                 rx_busy <= 1'b0;
80                 rx_count16 <= 4'd0;
81                 rx_bitcount <= 4'd0;
82         end else begin
83                 rx_irq <= 1'b0;
84
85                 if(enable16) begin
86                         if(~rx_busy) begin // look for start bit
87                                 if(rx2) begin // start bit found
88                                         rx_busy <= 1'b1;
89                                         rx_count16 <= 4'd11;
90                                         rx_bitcount <= 4'd0;
91                                 end
92                         end else begin
93                                 rx_count16 <= rx_count16 + 4'd1;
94
95                                 if(rx_count16 == 4'd0) begin // sample
96                                         rx_bitcount <= rx_bitcount + 4'd1;
97
98                                         if(rx_bitcount == 4'd0) begin // verify startbit
99                                                 if(~rx2)
100                                                         rx_busy <= 1'b0;
101                                         end else if(rx_bitcount == 4'd14) begin
102                                                 rx_busy <= 1'b0;
103                                                 rx_data <= rx_reg;
104                                                 rx_irq <= 1'b1;
105                                         end else
106                                                 rx_reg <= {rx_reg[11:0], rx2};
107                                 end
108                         end
109                 end
110         end
111 end
112
113 //-----------------------------------------------------------------
114 // CSR interface
115 //-----------------------------------------------------------------
116
117 wire csr_selected = csr_a[13:10] == csr_addr;
118
119 always @(posedge sys_clk) begin
120         if(sys_rst) begin
121                 csr_do <= 32'd0;
122         end else begin
123                 csr_do <= 32'd0;
124                 if(csr_selected)
125                         csr_do <= rx_data;
126         end
127 end
128
129 endmodule