Video input FIFO + DMA engine, untested
authorlekernel <sebastien.bourdeauducq@lekernel.net>
Mon, 28 Jun 2010 16:18:57 +0000 (18:18 +0200)
committerlekernel <sebastien.bourdeauducq@lekernel.net>
Mon, 28 Jun 2010 16:18:57 +0000 (18:18 +0200)
cores/bt656cap/rtl/bt656cap_burstmem.v [new file with mode: 0644]
cores/bt656cap/rtl/bt656cap_colorspace.v
cores/bt656cap/rtl/bt656cap_dma.v [new file with mode: 0644]
cores/bt656cap/rtl/bt656cap_input.v [new file with mode: 0644]

diff --git a/cores/bt656cap/rtl/bt656cap_burstmem.v b/cores/bt656cap/rtl/bt656cap_burstmem.v
new file mode 100644 (file)
index 0000000..847448f
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Milkymist VJ SoC
+ * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+module bt656cap_burstmem(
+       input sys_clk,
+
+       input we,
+       input [2:0] wa,
+       input [31:0] wd,
+
+       input [1:0] ra,
+       output [63:0] rd
+);
+
+reg [31:0] mem1[0:3];
+reg [31:0] mem1_do;
+always @(posedge sys_clk) begin
+       if(we & ~wa[0])
+               mem1[wa[2:1]] <= wd;
+       mem1_do <= mem1[ra];
+end
+
+reg [31:0] mem2[0:3];
+reg [31:0] mem2_do;
+always @(posedge sys_clk) begin
+       if(we & wa[0])
+               mem2[wa[2:1]] <= wd;
+       mem2_do <= mem2[ra];
+end
+
+assign rd = {mem1_do, mem2_do};
+
+endmodule
index d0efa54..fc5fd59 100644 (file)
@@ -24,8 +24,7 @@ module bt656cap_colorspace(
 
        output reg stb_o,
        output reg field_o,
-       output [15:0] rgb565_0,
-       output [15:0] rgb565_1
+       output [31:0] rgb565
 );
 
 /* Datapath */
@@ -115,8 +114,8 @@ always @(posedge vid_clk) begin
        end
 end
 
-assign rgb565_0 = {out_r0[7:3], out_g0[7:2], out_b0[7:3]};
-assign rgb565_1 = {out_r1[7:3], out_g1[7:2], out_b1[7:3]};
+assign rgb565 = {out_r0[7:3], out_g0[7:2], out_b0[7:3],
+       out_r1[7:3], out_g1[7:2], out_b1[7:3]};
 
 /* Forward field */
 always @(posedge vid_clk) begin
diff --git a/cores/bt656cap/rtl/bt656cap_dma.v b/cores/bt656cap/rtl/bt656cap_dma.v
new file mode 100644 (file)
index 0000000..24c2ca0
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Milkymist VJ SoC
+ * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+module bt656cap_dma #(
+       input fml_depth = 27
+) (
+       input sys_clk,
+       input sys_rst,
+
+       /* To/from control interface */
+       input [1:0] field_filter,
+       output [fml_depth-1-1:0] fml_adr_base,
+       output start_of_frame,
+       output reg next_burst,
+       input last_burst,
+
+       /* From video input module. */
+       input v_stb,
+       output reg v_ack,
+       input v_field,
+       input [31:0] v_rgb565,
+
+       /* FML interface. fml_we=1 is assumed. */
+       output [fml_depth-1:0] fml_adr,
+       output reg fml_stb,
+       input fml_ack,
+       output [63:0] fml_do
+);
+
+/* Data buffer */
+reg data_en;
+reg [2:0] v_bcount;
+reg burst_7;
+always @(posedge sys_clk) begin
+       if(sys_rst)
+               v_bcount <= 3'd0;
+       else if(v_stb & v_ack & data_en) begin
+               v_bcount <= v_bcount + 3'd1;
+               burst_7 <= v_bcount == 3'd6;
+       end
+end
+
+reg [1:0] f_bcount;
+
+bt656cap_burstmem burstmem(
+       .sys_clk(sys_clk),
+
+       .we(v_stb & v_ack & data_en),
+       .wa(v_bcount),
+       .wd(v_rgb565),
+
+       .ra(f_bcount),
+       .rd(fml_do)
+);
+
+/* FML address generator */
+reg [fml_adr-1-5:0] fml_adr_b;
+
+always @(posedge sys_clk) begin
+       if(start_of_frame)
+               fml_adr_b <= fml_adr_base;
+       else if(next_burst)
+               fml_adr_b <= fml_adr_b + 1'd1;
+end
+
+assign fml_adr = {fml_adr_b, 5'd0};
+
+/* Detect start of frames and filter fields */
+reg previous_field;
+always @(posedge sys_clk) begin
+       if(v_stb & v_ack)
+               previous_field <= v_field;
+end
+
+assign start_of_frame = (v_stb & v_ack) &
+       ((field_filter[0] & previous_field & ~v_field)
+       |(field_filter[1] & ~previous_field & v_field));
+
+/* Controller */
+reg [2:0] state;
+reg [2:0] next_state;
+
+parameter WAIT_SOF = 3'd0;
+parameter WAIT_EOB = 3'd1;
+parameter TRANSFER1 = 3'd2;
+parameter TRANSFER2 = 3'd3;
+parameter TRANSFER3 = 3'd4;
+parameter TRANSFER4 = 3'd6;
+
+always @(posedge sys_clk) begin
+       if(sys_rst)
+               state <= WAIT_SOF;
+       else
+               stats <= next_state;
+end
+
+always @(*) begin
+       v_ack = 1'b0;
+       fml_stb = 1'b0;
+       next_burst = 1'b0;
+
+       data_en = 1'b0;
+
+       f_bcount = 2'bx;
+
+       next_state = state;
+
+       case(state)
+               WAIT_SOF: begin
+                       v_ack = 1'b1;
+                       data_en = start_of_frame;
+                       if(start_of_frame)
+                               next_state = WAIT_EOB;
+               end
+               WAIT_EOB: begin
+                       v_ack = 1'b1;
+                       data_en = 1'b1;
+                       f_bcount = 2'd0;
+                       if(burst_7 & v_stb)
+                               next_state = TRANSFER1;
+               end
+               TRANSFER1: begin
+                       fml_stb = 1'b1;
+                       f_bcount = 2'd0;
+                       if(fml_ack) begin
+                               f_bcount = 2'd1;
+                               next_state = TRANSFER2;
+                       end
+               end
+               TRANSFER2: begin
+                       f_bcount = 2'd2;
+                       next_burst = 1'b1;
+                       next_state = TRANSFER3;
+               end
+               TRANSFER3: begin
+                       f_bcount = 2'd3;
+                       next_state = TRANSFER4;
+               end
+               TRANSFER4: begin
+                       if(last_burst)
+                               next_state = WAIT_SOF;
+                       else
+                               next_state = WAIT_EOB;
+               end
+       endcase
+
+end
+
+endmodule
diff --git a/cores/bt656cap/rtl/bt656cap_input.v b/cores/bt656cap/rtl/bt656cap_input.v
new file mode 100644 (file)
index 0000000..135f8fa
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Milkymist VJ SoC
+ * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+module bt656cap_input(
+       input sys_clk,
+       input vid_clk,
+
+       input [7:0] p,
+
+       output stb,
+       input ack,
+       output field,
+       output [31:0] rgb565
+);
+
+wire decoder_stb;
+wire decoder_field;
+wire [31:0] decoder_ycc422;
+bt656cap_decoder decoder(
+       .vid_clk(vid_clk),
+       .p(p),
+
+       .stb(decoder_stb),
+       .field(decoder_field),
+       .ycc422(decoder_ycc422)
+);
+
+wire colorspace_stb;
+wire colorspace_field;
+wire [31:0] colorspace_rgb565;
+bt656cap_colorspace colorspace(
+       .vid_clk(vid_clk),
+
+       .stb_i(decoder_stb),
+       .field_i(decoder_field),
+       .ycc422(decoder_ycc422),
+
+       .stb_o(colorspace_stb),
+       .field_o(colorspace_field),
+       .rgb565(colorspace_rgb565)
+);
+
+wire empty;
+asfifo #(
+       .data_width(33),
+       .address_width(5)
+) fifo (
+       .data_out({field, rgb565}),
+       .empty(empty),
+       .read_en(ack),
+       .clk_read(sys_clk),
+
+       .data_in({colorspace_field, colorspace_rgb565}),
+       .full(),
+       .write_en(colorspace_stb),
+       .clk_write(vid_clk),
+
+       .rst(1'b0)
+);
+assign stb = ~empty;
+
+endmodule