Integrated video in. Working but cleanup-needing I2C functions.
[mw/milkymist.git] / cores / bt656cap / test / tb_bt656cap.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 tb_bt656cap();
19
20 parameter fml_depth = 26;
21
22 reg sys_clk;
23 reg sys_rst;
24
25 reg [13:0] csr_a;
26 reg csr_we;
27 reg [31:0] csr_di;
28 wire [31:0] csr_do;
29
30 wire irq;
31
32 wire [fml_depth-1:0] fml_adr;
33 wire fml_stb;
34 reg fml_ack;
35 wire [63:0] fml_do;
36
37 reg vid_clk;
38 reg [7:0] p;
39
40 /* 100MHz system clock */
41 initial sys_clk = 1'b0;
42 always #5 sys_clk = ~sys_clk;
43
44 /* ~27MHz video clock */
45 initial vid_clk = 1'b0;
46 always #19 vid_clk = ~vid_clk;
47
48 reg field;
49 reg [19:0] inc;
50 initial field = 1'b0;
51 initial inc = 20'd0;
52 always @(posedge vid_clk) begin
53         inc <= inc + 20'd1;
54         p <= {inc[7:1], 1'b0};
55         if(inc == 20'd414720) begin
56                 field <= ~field;
57                 p <= 8'hff;
58         end
59         if(inc == 20'd414721) p <= 8'h00;
60         if(inc == 20'd414722) p <= 8'h00;
61         if(inc == 20'd414723) begin
62                 p <= {1'b1, field, 6'b00_0000};
63                 inc <= 20'd0;
64                 $display("** end of frame");
65         end
66 end
67
68 bt656cap #(
69         .fml_depth(fml_depth)
70 ) dut (
71         .sys_clk(sys_clk),
72         .sys_rst(sys_rst),
73         
74         .csr_a(csr_a),
75         .csr_we(csr_we),
76         .csr_di(csr_di),
77         .csr_do(csr_do),
78         
79         .irq(irq),
80         
81         .fml_adr(fml_adr),
82         .fml_stb(fml_stb),
83         .fml_ack(fml_ack),
84         .fml_do(fml_do),
85
86         .vid_clk(vid_clk),
87         .p(p),
88         .sda(),
89         .sdc()
90 );
91
92 task waitclock;
93 begin
94         @(posedge sys_clk);
95         #1;
96 end
97 endtask
98
99 task csrwrite;
100 input [31:0] address;
101 input [31:0] data;
102 begin
103         csr_a = address[16:2];
104         csr_di = data;
105         csr_we = 1'b1;
106         waitclock;
107         $display("CSR write: %x=%x", address, data);
108         csr_we = 1'b0;
109 end
110 endtask
111
112 task csrread;
113 input [31:0] address;
114 begin
115         csr_a = address[16:2];
116         waitclock;
117         $display("CSR read : %x=%x", address, csr_do);
118 end
119 endtask
120
121 /* Handle FML master for pixel writes */
122 integer write_burstcount;
123 integer write_addr;
124
125 task handle_write;
126 integer write_addr2;
127 integer x;
128 integer y;
129 begin
130         write_addr2 = write_addr[20:0]/2;
131         x = write_addr2 % 720;
132         y = write_addr2 / 720;
133         $display("W: %d %d", x, y);
134         $image_set(x + 0, y, fml_do[63:48]);
135         $image_set(x + 1, y, fml_do[47:32]);
136         $image_set(x + 2, y, fml_do[31:16]);
137         $image_set(x + 3, y, fml_do[15:0]);
138 end
139 endtask
140
141 initial write_burstcount = 0;
142 always @(posedge sys_clk) begin
143         fml_ack = 1'b0;
144         if(write_burstcount == 0) begin
145                 if(fml_stb & (($random % 5) == 0)) begin
146                         write_burstcount = 1;
147                         write_addr = fml_adr;
148                         
149                         $display("Starting   FML burst WRITE at address %x data=%x", write_addr, fml_do);
150                         handle_write;
151                         
152                         fml_ack = 1'b1;
153                 end
154         end else begin
155                 write_addr = write_addr + 8;
156                 write_burstcount = write_burstcount + 1;
157                 
158                 $display("Continuing FML burst WRITE at address %x data=%x", write_addr, fml_do);
159                 handle_write;
160                 
161                 if(write_burstcount == 4)
162                         write_burstcount = 0;
163         end
164 end
165
166 always begin
167         $image_open;
168         
169         /* Reset / Initialize our logic */
170         sys_rst = 1'b1;
171         
172         csr_a = 14'd0;
173         csr_di = 32'd0;
174         csr_we = 1'b0;
175
176         fml_ack = 1'b0;
177         
178         waitclock;
179         
180         sys_rst = 1'b0;
181         
182         waitclock;
183
184         /* Setup */
185         $display("Configuring DUT...");
186         csrwrite(32'h04, 32'h03);
187         csrread(32'h04);
188         @(posedge irq);
189         csrread(32'h04);
190         @(posedge irq);
191         csrread(32'h04);
192         @(posedge irq);
193
194         $image_close;
195         $finish;
196 end
197
198 endmodule