// MT9D111 Camera Controller for AXI4-Stream
// mt9d111_cam_contss.v
// 2013/05/29
//
`default_nettype none
module mt9d111_cam_conts (
input wire pclk,
input wire preset,
input wire pclk_from_pll,
output wire xclk,
input wire line_valid,
input wire frame_valid,
input wire [7:0] cam_data,
output wire standby,
output wire s2mm_fsync,
output wire pfifo_empty,
output wire pfifo_almost_empty,
input wire pfifo_rd_en,
output wire [24:0] pfifo_dout,
output wire pfifo_overflow,
output wire pfifo_underflow
);
reg line_valid_1d, line_valid_2d;
reg frame_valid_1d, frame_valid_2d;
reg [7:0] cam_data_1d;
reg line_valid_1d_odd;
reg line_v_1d_odd_1d, line_v_1d_odd_2d, line_v_1d_odd_3d;
reg [23:0] rgb565, rgb565_2d;
wire [24:0] pfifo_din;
wire pfifo_full, pfifo_almost_full;
reg s2mm_fsync_node;
assign standby = 1'b0;
// MT9D111 へのクロックを出力 (xclk)
ODDR #(
.DDR_CLK_EDGE("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
.INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1
.SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
) ODDR_inst (
.Q(xclk), // 1-bit DDR output
.C(pclk_from_pll), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D1(1'b1), // 1-bit data input (positive edge)
.D2(1'b0), // 1-bit data input (negative edge)
.R(1'b0), // 1-bit reset
.S(1'b0) // 1-bit set
);
// 入力信号を一旦ラッチする
always @(posedge pclk) begin
if (preset) begin
line_valid_1d <= 1'b0;
line_valid_2d <= 1'b0;
frame_valid_1d <= 1'b0;
frame_valid_2d <= 1'b0;
cam_data_1d <= 8'd0;
end else begin
line_valid_1d <= line_valid;
line_valid_2d <= line_valid_1d;
frame_valid_1d <= frame_valid;
frame_valid_2d <= frame_valid_1d;
cam_data_1d <= cam_data;
end
end
// line_valid_1d が偶数か奇数かをカウント
always @(posedge pclk) begin
if (preset)
line_valid_1d_odd <= 1'b0;
else begin
if (line_valid_1d)
line_valid_1d_odd <= ~line_valid_1d_odd;
else
line_valid_1d_odd <= 1'b0;
end
end
// rgb565でラッチしているので、line_valid_1d_odd を1クロック遅延する
always @(posedge pclk) begin
if (preset) begin
line_v_1d_odd_1d <= 1'b0;
line_v_1d_odd_2d <= 1'b0;
line_v_1d_odd_3d <= 1'b0;
end else begin
line_v_1d_odd_1d <= line_valid_1d_odd;
line_v_1d_odd_2d <= line_v_1d_odd_1d;
line_v_1d_odd_3d <= line_v_1d_odd_2d;
end
end
// rgb565
always @(posedge pclk) begin
if (preset)
rgb565 <= 24'd0;
else begin
if (~line_valid_1d_odd)
rgb565[23:13] <= {cam_data_1d[7:3], 3'b000, cam_data_1d[2:0]}; // cam_data_1d = R7 R6 R5 R4 R3 G7 G6 G5
else
rgb565[12:0] <= {cam_data_1d[7:5], 2'b00, cam_data_1d[4:0], 3'b000}; // cam_data_1d = G4 G3 G2 B7 B6 B5 B4 B3
end
end
// rgb565_2d, データを2クロック遅らせて、tlastを最後から1つ前のデータに付加する
always @(posedge pclk) begin
if (preset)
rgb565_2d <= 24'd0;
else begin
if (line_v_1d_odd_1d)
rgb565_2d <= rgb565;
end
end
assign pfifo_din = {((line_valid_2d & ~line_valid_1d) ? 1'b1 : 1'b0), rgb565_2d}; // line_valid_1d の立ち下がりエッジ
// pixel FIFO をインスタンスする
pixel_fifo pfifo (
.clk(pclk),
.srst(preset), // input rst
.din(pfifo_din), // input [24 : 0] din
.wr_en(line_v_1d_odd_3d), // input wr_en
.rd_en(pfifo_rd_en), // input rd_en
.dout(pfifo_dout), // output [24 : 0] dout
.full(pfifo_full), // output full
.almost_full(pfifo_almost_full), // output almost_full
.overflow(pfifo_overflow), // output overflow
.empty(pfifo_empty), // output empty
.almost_empty(pfifo_almost_empty), // output almost_empty
.underflow(pfifo_underflow) // output underflow
);
// s2mm_fsync
always @(posedge pclk) begin
if (preset)
s2mm_fsync_node <= 1'b0;
else begin
if (frame_valid_1d==1'b1 && frame_valid_2d==1'b0) // frame_valid_1d の立ち上がり
s2mm_fsync_node <= 1'b1;
else
s2mm_fsync_node <= 1'b0;
end
end
assign s2mm_fsync = s2mm_fsync_node;
endmodule
`default_nettype wire
-------------------------------------------------------------------------------
-- Filename: mt9d111_inf_axi_stream.vhd
-- Description: An AXI Stream interface
--
-- VHDL-Standard: VHDL'93
-------------------------------------------------------------------------------
-- Structure:
-- mt9d111_inf_axi_stream.vhd
--
-- AXI4-Stream データの出力は2クロックに1回とする
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
--library unisim;
--use unisim.vcomponents.all;
-------------------------------------------------------------------------------
entity mt9d111_inf_axi_stream is
generic(
-- Master AXI Stream Data Width
C_M_AXIS_DATA_WIDTH : integer range 8 to 1024 := 24
);
port (
s2mm_aclk : out std_logic;
s2mm_prmry_reset : in std_logic;
s2mm_fsync : out std_logic;
-- Master Stream Ports
-- m_axis_aresetn : out std_logic;
m_axis_tdata : out std_logic_vector(C_M_AXIS_DATA_WIDTH-1 downto 0);
m_axis_tstrb : out std_logic_vector((C_M_AXIS_DATA_WIDTH/8)-1 downto 0);
m_axis_tvalid : out std_logic;
m_axis_tready : in std_logic;
m_axis_tlast : out std_logic;
init_done : in std_logic; -- PS部の初期化終了
-- MT9D111 Camera Interface
pclk_from_pll : in std_logic; -- PLLからMT9D111のxck に出力するクロック
pclk : in std_logic; -- MT9D111からのピクセルクロック入力
xck : out std_logic; -- MT9D111へのピクセルクロック出力
href : in std_logic;
vsync : in std_logic;
cam_data : in std_logic_vector(7 downto 0);
standby : out std_logic; -- STANDBY出力(ディスエーブル、0固定)
pfifo_overflow : out std_logic; -- pfifo overflow
pfifo_underflow : out std_logic -- pfifo underflow
);
end mt9d111_inf_axi_stream;
-------------------------------------------------------------------------------
-- Architecture
-------------------------------------------------------------------------------
architecture implementation of mt9d111_inf_axi_stream is
signal pfifo_empty : std_logic;
signal pfifo_almost_empty : std_logic;
signal pfifo_rd_en : std_logic;
signal pfifo_dout : std_logic_vector(24 downto 0);
signal rst_1d, rst_2d, reset : std_logic;
signal tlast : std_logic;
type tlast_state is (idle_tlast, tlast_assert);
signal tlast_sm : tlast_state;
signal tvalid : std_logic;
type tvalid_state is (idle_tvalid, tvalid_assert);
signal tvalid_sm : tvalid_state;
component mt9d111_cam_conts
port (
pclk : in std_logic;
preset : in std_logic;
pclk_from_pll : in std_logic;
xclk : out std_logic;
line_valid : in std_logic;
frame_valid : in std_logic;
cam_data : in std_logic_vector(7 downto 0);
standby : out std_logic;
s2mm_fsync : out std_logic;
pfifo_empty : out std_logic;
pfifo_almost_empty : out std_logic;
pfifo_rd_en : in std_logic;
pfifo_dout : out std_logic_vector(24 downto 0);
pfifo_overflow : out std_logic;
pfifo_underflow : out std_logic
);
end component;
begin
s2mm_aclk <= pclk;
mt9d111_camc : mt9d111_cam_conts port map(
pclk => pclk,
preset => reset,
pclk_from_pll => pclk_from_pll,
xclk => xck,
line_valid => href,
frame_valid => vsync,
cam_data => cam_data,
standby => standby,
s2mm_fsync => s2mm_fsync,
pfifo_empty => pfifo_empty,
pfifo_almost_empty => pfifo_almost_empty,
pfifo_rd_en => pfifo_rd_en,
pfifo_dout => pfifo_dout,
pfifo_overflow => pfifo_overflow,
pfifo_underflow => pfifo_underflow
);
-- Synchronization by pclk
process(pclk) begin
rst_1d <= s2mm_prmry_reset or not init_done;
rst_2d <= rst_1d;
end process;
reset <= rst_2d;
-- State Machine for tlast
process(pclk) begin
if pclk'event and pclk='1' then
if reset='1' then
tlast_sm <= idle_tlast;
tlast <= '0';
else
case tlast_sm is
when idle_tlast =>
if pfifo_dout(24)='1' and tvalid='1' and m_axis_tready='1' and pfifo_empty='0' then
tlast_sm <= tlast_assert;
tlast <= '1';
end if;
when tlast_assert =>
if m_axis_tready='1' then
tlast_sm <= idle_tlast;
tlast <= '0';
end if;
end case;
end if;
end if;
end process;
m_axis_tlast <= tlast;
-- State Machine for tvalid
process(pclk) begin
if pclk'event and pclk='1' then
if reset='1' then
tvalid_sm <= idle_tvalid;
tvalid <= '0';
else
case tvalid_sm is
when idle_tvalid =>
if pfifo_empty='0' then -- pfifo にデータがある
tvalid_sm <= tvalid_assert;
tvalid <= '1';
end if;
when tvalid_assert =>
if m_axis_tready='1' and pfifo_almost_empty='1' then -- 次のデータがない場合はidle に戻る
tvalid_sm <= idle_tvalid;
tvalid <= '0';
end if;
end case;
end if;
end if;
end process;
m_axis_tvalid <= tvalid;
pfifo_rd_en <= tvalid and m_axis_tready;
m_axis_tdata <= pfifo_dout(23 downto 0);
m_axis_tstrb <= (others => '1');
end implementation;
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | - | - | - | - |