Video in testbench
[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 reg 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                 field_filter <= 2'd0;
68                 fml_adr_base <= {fml_depth-5{1'b0}};
69                 max_bursts <= 15'd13824;
70
71                 sda_oe <= 1'b0;
72                 sda_o <= 1'b0;
73                 sdc <= 1'b0;
74         end else begin
75                 csr_do <= 32'd0;
76
77                 if(csr_selected) begin
78                         if(csr_we) begin
79                                 case(csr_a[2:0])
80                                         3'd0: begin
81                                                 sda_o <= csr_di[1];
82                                                 sda_oe <= csr_di[2];
83                                                 sdc <= csr_di[3];
84                                         end
85                                         3'd1: field_filter <= csr_di[1:0];
86                                         3'd2: fml_adr_base <= csr_di[fml_depth-1:5];
87                                         3'd3: max_bursts <= csr_di[14:0];
88                                 endcase
89                         end
90
91                         case(csr_a[2:0])
92                                 3'd0: csr_do <= {sdc, sda_oe, sda_o, sda_2};
93                                 3'd1: csr_do <= {in_frame, field_filter};
94                                 3'd2: csr_do <= {fml_adr_base, 5'd0};
95                                 3'd3: csr_do <= max_bursts;
96                                 3'd4: csr_do <= done_bursts;
97                         endcase
98                 end
99         end
100 end
101
102 always @(posedge sys_clk) begin
103         if(sys_rst)
104                 irq <= 1'b0;
105         else
106                 irq <= start_of_frame;
107 end
108
109 reg [14:0] burst_counter;
110 always @(posedge sys_clk) begin
111         if(sys_rst) begin
112                 last_burst <= 1'b0;
113                 burst_counter <= 15'd0;
114         end else begin
115                 if(start_of_frame) begin
116                         last_burst <= 1'b0;
117                         burst_counter <= 15'd0;
118                         done_bursts <= burst_counter;
119                 end
120                 if(next_burst) begin
121                         burst_counter <= burst_counter + 15'd1;
122                         last_burst <= (burst_counter + 15'd1) == max_bursts;
123                 end
124         end
125 end
126
127 endmodule