ae2f4f3a7797505459f7185aef59c59eb6045fef
[mw/milkymist.git] / cores / bt656cap / rtl / bt656cap_ctlif.v
1 /*
2  * Milkymist VJ SoC
3  * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, version 3 of the License.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 module bt656cap_ctlif #(
19         parameter csr_addr = 4'h0,
20         parameter fml_depth = 27
21 ) (
22         input sys_clk,
23         input sys_rst,
24
25         input [13:0] csr_a,
26         input csr_we,
27         input [31:0] csr_di,
28         output reg [31:0] csr_do,
29
30         output reg irq,
31
32         output reg [1:0] field_filter,
33         input in_frame,
34         output reg [fml_depth-1-5:0] fml_adr_base,
35         input start_of_frame,
36         input next_burst,
37         output reg last_burst,
38
39         inout sda,
40         output sdc
41 );
42
43 /* I2C */
44 reg sda_1;
45 reg sda_2;
46 reg sda_oe;
47 reg sda_o;
48
49 always @(posedge sys_clk) begin
50         sda_1 <= sda;
51         sda_2 <= sda_1;
52 end
53
54 assign sda = sda_oe ? sda_o : 1'bz;
55
56 /* CSR IF */
57
58 wire csr_selected = csr_a[13:10] == csr_addr;
59
60 reg [14:0] max_bursts;
61 reg [14:0] done_bursts;
62
63 always @(posedge sys_clk) begin
64         if(sys_rst) begin
65                 csr_do <= 32'd0;
66
67                 sda_oe <= 1'b0;
68                 sda_o <= 1'b0;
69         end else begin
70                 csr_do <= 32'd0;
71
72                 if(csr_selected) begin
73                         if(csr_we) begin
74                                 case(csr_a[2:0])
75                                         3'd0: begin
76                                                 sda_o <= csr_di[1];
77                                                 sda_oe <= csr_di[2];
78                                         end
79                                         3'd1: field_filter <= csr_di[1:0];
80                                         3'd2: fml_adr_base <= csr_di[fml_depth-1:5];
81                                         3'd3: max_bursts <= csr_di[14:0];
82                                 endcase
83                         end
84
85                         case(csr_a[2:0])
86                                 3'd0: csr_do <= {sda_oe, sda_o, sda_2};
87                                 3'd1: csr_do <= {in_frame, field_filter};
88                                 3'd2: csr_do <= {fml_adr_base, 5'd0};
89                                 3'd3: csr_do <= max_bursts;
90                                 3'd4: csr_do <= done_bursts;
91                         endcase
92                 end
93         end
94 end
95
96 always @(posedge sys_clk) begin
97         if(sys_rst)
98                 irq <= 1'b0;
99         else
100                 irq <= start_of_frame;
101 end
102
103 reg [14:0] burst_counter;
104 always @(posedge sys_clk) begin
105         if(sys_rst) begin
106                 last_burst <= 1'b0;
107                 burst_counter <= 15'd0;
108         end else begin
109                 if(start_of_frame) begin
110                         last_burst <= 1'b0;
111                         burst_counter <= 15'd0;
112                         done_bursts <= burst_counter;
113                 end
114                 if(next_burst) begin
115                         burst_counter <= burst_counter + 15'd1;
116                         last_burst <= (burst_counter + 15'd1) == max_bursts;
117                 end
118         end
119 end
120
121 endmodule