としたら、CMOSカメラから出力が出てきた。うれしかった!n_cam_reset <= '0'; -- OV7640のRESETはアクティブハイ
n_mem_rd <= not r_w;
-- その他のモジュールの動作は1クロック遅れるので、最初はwrite_stateとなる
process(cs_rw, cs_sync, cam_href_1d) begin
case cs_rw is
when idle_rw =>
r_w_node <= '1';
if cs_sync=vsync_deassert and cam_href_1d='1' then
ns_rw <= write_state;
else
ns_rw <= idle_rw;
end if;
when read_state =>
r_w_node <= '1';
if cs_sync=vsync_deassert and cam_href_1d='1' then
ns_rw <= read_state;
else
ns_rw <= write_state;
end if;
when write_state =>
r_w_node <= '0';
if cs_sync=vsync_deassert and cam_href_1d='1' then
ns_rw <= read_state;
else
ns_rw <= read_state;
end if;
end case;
end process;
r_w <= r_w_node;
-- その他のモジュールの動作は1クロック遅れるので、最初はwrite_stateとなる
process(cs_rw, cs_sync, cam_href_1d) begin
case cs_rw is
when idle_rw =>
r_w_node <= '1';
if cs_sync=vsync_deassert and cam_href_1d='1' then
ns_rw <= write_state;
else
ns_rw <= idle_rw;
end if;
when read_state =>
r_w_node <= '1';
if cs_sync=vsync_deassert and cam_href_1d='1' then
ns_rw <= write_state;
else
ns_rw <= write_state;
end if;
when write_state =>
r_w_node <= '0';
if cs_sync=vsync_deassert and cam_href_1d='1' then
ns_rw <= write_state;
else
ns_rw <= read_state;
end if;
end case;
end process;
r_w <= r_w_node;
-- CMOSカメラ用のリセットを出力する(1.37ms)
-- CMOSカメラのRESETを出力するために32,768カウントする。(41.67ns * 32768 = 1.37ms)
process(cam_clk_node) begin
if cam_clk_node'event and cam_clk_node='1' then
if cam_clk_locked='0' then
cam_rst_cnt <= (others => '0');
elsif cam_rst_cnt(15)='0' then -- 最上位が0の時はカウントして、1のなったらそこで停止
cam_rst_cnt <= cam_rst_cnt + 1;
end if;
end if;
end process;
n_cam_reset <= cam_rst_cnt(15); -- CMOSカメラ用のリセットを出力する(1.37ms)
cam_sio_c <= '1';
cam_sio_d <= 'Z';
-- synchronizer
-- synchronizerが使用するのは、FPGAに入力されたcam_hrefやcam_vsyncからIOBのFFを通り1クロックディレイした信号。その他のモジュールは2クロック遅延した信号を用いる
-- cam_vsync_1d が1から0になった後の最初の cam_href_1d の立ち上がりで同期信号(master_sync)を出力する
-- 同時に出力するR_W信号を1(Read)にする
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
entity synchronizer is
port(
clk : in std_logic;
reset : in std_logic;
cam_vsync_1d : in std_logic;
cam_href_1d : in std_logic;
master_sync : out std_logic;
r_w : out std_logic
);
end synchronizer;
architecture RTL of synchronizer is
type sync_state is (idle_sync, vsync_assert, vsync_deassert, sync_active);
signal cs_sync, ns_sync : sync_state;
type rw_state is (idle_rw, read_state, write_state);
signal cs_rw, ns_rw : rw_state;
signal msync : std_logic;
signal r_w_node : std_logic;
begin
-- master_syncを出力するステートマシン
process(clk) begin
if clk'event and clk='1' then
if reset='1' then
cs_sync <= idle_sync;
else
cs_sync <= ns_sync;
end if;
end if;
end process;
process(cs_sync, cam_vsync_1d, cam_href_1d) begin
msync <= '0';
case cs_sync is
when idle_sync =>
if cam_vsync_1d='1' then
ns_sync <= vsync_assert;
else
ns_sync <= idle_sync;
end if;
when vsync_assert =>
if cam_vsync_1d='0' then
ns_sync <= vsync_deassert;
else
ns_sync <= vsync_assert;
end if;
when vsync_deassert =>
if cam_href_1d='1' then
ns_sync <= sync_active;
else
ns_sync <= vsync_deassert;
end if;
when sync_active =>
msync <= '1';
ns_sync <= idle_sync;
end case;
end process;
master_sync <= msync;
-- r_wを出力するステートマシン
process(clk) begin
if clk'event and clk='1' then
if reset='1' then
cs_rw <= idle_rw;
else
cs_rw <= ns_rw;
end if;
end if;
end process;
-- その他のモジュールの動作は1クロック遅れるので、最初はwrite_stateとなる
process(cs_rw, cs_sync, cam_href_1d) begin
case cs_rw is
when idle_rw =>
r_w_node <= '1';
if cs_sync=vsync_deassert and cam_href_1d='1' then
ns_rw <= write_state;
else
ns_rw <= idle_rw;
end if;
when read_state =>
r_w_node <= '1';
if cs_sync=vsync_deassert and cam_href_1d='1' then
ns_rw <= read_state;
else
ns_rw <= write_state;
end if;
when write_state =>
r_w_node <= '0';
if cs_sync=vsync_deassert and cam_href_1d='1' then
ns_rw <= read_state;
else
ns_rw <= read_state;
end if;
end case;
end process;
r_w <= r_w_node;
end RTL;
--CamDisplay Contoroller with SRAM(トップモジュール)-- トップモジュールから全部作ることにする。
-- CMOSカメラから出てくるビデオ出力はUYVYとする
-- VSYNCは正論理、HREFも正論理
-- clk(48MHz)はそのまま使用して、PCLKをDCMで受けて使用する。
-- IOBにマップされるロジックはこのトップモジュールにインスタンシエーションする。
-- synchronizerでは_1dのデータを使用し、その他のモジュールでは_2dのデータを使用する
-- 全体のタイミングは_2dを基準とする
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
-- pragma translate_off
library UNISIM;
use UNISIM.VComponents.all;
-- pragma translate_on
entity CamDispCntrl_SRAM is
port (
clk : in std_logic; -- 水晶発振器からの48MHzクロック
cam_vsync : in std_logic; -- CMOSカメラからのVSYNC
cam_href : in std_logic; -- CMOSカメラからのHREF
cam_pclk : in std_logic; -- CMOSカメラからのpclk
cam_ydata : in std_logic_vector(7 downto 0); -- CMOSカメラからのYデータ
-- cam_sio_c : out std_logic; -- CMOSカメラのI2Cクロック
-- cam_sio_d : inout std_logic; -- CMOSカメラのI2Cデータ
cam_clk : out std_logic; -- CMOSカメラのクロック
n_cam_reset : out std_logic; -- CMOSカメラのリセット(Lでリセットの予定)
dac_red : out std_logic_vector(7 downto 0); -- DACへのRED出力
dac_green : out std_logic_vector(7 downto 0); -- DACへのGREEN出力
dac_blue : out std_logic_vector(7 downto 0); -- DACへのBLUE出力
n_dac_blank : out std_logic; -- DACへのアクティブローBLANK
dac_clk : out std_logic; -- DACクロック(24MHz)
vga_vsync : out std_logic; -- VGAのVSYNC
vga_hsync : out std_logic; -- VGAのHSYNC
mem_data : inout std_logic_vector(15 downto 0); -- SRAMのmemory data
n_mem_we : out std_logic; -- SRAMのmemory write enable
n_mem_rd : out std_logic; -- SRAMのmemory read enable
n_mem_cs0 : out std_logic; -- SRAMのchip select 0
n_mem_cs1 : out std_logic; -- SRAMのchip select 1
n_mem_cs2 : out std_logic; -- SRAMのchip select 2
n_mem_cs3 : out std_logic; -- SRAMのchip select 3
n_mem_lowerB : out std_logic; -- SRAMのmemory lower byte enable
n_mem_upperB : out std_logic; -- SRAMのmemory upper byte enable
mem_addr : out std_logic_vector(17 downto 0) -- SRAMのmemory address
);
end CamDispCntrl_SRAM;
architecture RTL of CamDispCntrl_SRAM is
component DCM_module_24MHz
port(
clk48MHz_in : in std_logic;
clk48_out : out std_logic;
cam_clk_out : out std_logic;
pclk_in : in std_logic;
mclk_out : out std_logic;
cam_clk_locked : out std_logic;
mclk_locked : out std_logic
);
end component;
component ODDR2
generic(
DDR_ALIGNMENT : string := "NONE";
INIT : bit := '0';
SRTYPE : string := "SYNC"
);
port(
Q : out std_ulogic;
C0 : in std_ulogic;
C1 : in std_ulogic;
CE : in std_ulogic := 'H';
D0 : in std_ulogic;
D1 : in std_ulogic;
R : in std_ulogic := 'L';
S : in std_ulogic := 'L'
);
end component;
component VGA_Display_Controller
port(
clk : in std_logic;
reset : in std_logic;
master_sync : in std_logic; -- 表示タイミングの同期信号
pixel_y_data : in std_logic_vector(15 downto 0); -- Yのデータ、下のdata_enableが1の時に有効
data_enable : in std_logic;
h_count_out : out unsigned(9 downto 0); -- 水平カウンタのカウント出力
v_count_out : out unsigned(9 downto 0); -- 垂直カウンタのカウント出力
red_out : out std_logic_vector(7 downto 0); -- VGA出力
green_out : out std_logic_vector(7 downto 0); -- VGA出力
blue_out : out std_logic_vector(7 downto 0); -- VGA出力
blank_out : out std_logic; -- BLANK出力
h_syncx_out : out std_logic; -- 水平同期出力
v_syncx_out : out std_logic; -- 垂直同期出力
mem_addr : out std_logic_vector(18 downto 0) -- SRAMのアドレス、バイト単位
);
end component;
component synchronizer
port(
clk : in std_logic;
reset : in std_logic;
cam_vsync_1d : in std_logic;
cam_href_1d : in std_logic;
master_sync : out std_logic;
r_w : out std_logic
);
end component;
component SRAM_Controller
port(
clk : in std_logic;
clk48 : in std_logic;
reset : in std_logic;
r_w : in std_logic; -- Read or Write
cam_href_3d : in std_logic; -- cam_href の3クロック遅れ、各モジュールで2クロック遅れの信号を使っているので、それよりも1クロック遅れている信号をweのイネーブルとして使用する。これはUYVYとデータが来るので、サンプルするのに1クロック遅れるから。
master_sync : in std_logic;
cam_mem_addr : in std_logic_vector(17 downto 0); -- CMOSカメラの書き込み用のアドレス
cam_ydata_in : in std_logic_vector(7 downto 0); -- CMOSカメラのデータ
vga_mem_addr : in std_logic_vector(18 downto 1); -- VGAコントローラー用読み出し用アドレス
mem_data_out : out std_logic_vector(15 downto 0); -- SRAMのデータ出力。CMOSカメラのデータを2つ集めたもの。
mem_data_oe : out std_logic; -- SRAMのmemory data出力のOutput Enable
n_mem_we : out std_logic; -- SRAMのWE
n_mem_cs0 : out std_logic; -- SRAMのchip select 0
n_mem_cs1 : out std_logic; -- SRAMのchip select 1
n_mem_cs2 : out std_logic; -- SRAMのchip select 2
n_mem_cs3 : out std_logic; -- SRAMのchip select 3
n_mem_lowerB : out std_logic; -- SRAMのmemory lower byte enable
n_mem_upperB : out std_logic; -- SRAMのmemory upper byte enable
mem_addr : out std_logic_vector(17 downto 0) -- SRAMのmemory address
);
end component;
component Camera_Controller
port(
clk : in std_logic;
reset : in std_logic;
cam_href_2d : in std_logic; -- CMOSカメラからのHREFのラッチ出力
master_sync : in std_logic; -- 同期信号
mem_addr : out std_logic_vector(17 downto 0) -- CMOSカメラのデータを書き込むSRAMのアドレス
);
end component;
component IOBUF
port(
O : out std_logic;
IO : inout std_logic;
I : in std_logic;
T : in std_logic
);
end component;
signal mclk : std_logic;
signal reset : std_logic;
signal mclk_locked : std_logic;
signal master_sync : std_logic;
signal r_w : std_logic;
signal cam_href_1d, cam_vsync_1d : std_logic;
signal cam_href_3d : std_logic;
signal cam_href_2d, cam_vsync_2d : std_logic;
signal cam_ydata_1d, cam_ydata_2d : std_logic_vector(7 downto 0);
signal w_r : std_logic;
signal vga_blank : std_logic;
signal vga_mem_addr : std_logic_vector(17 downto 0);
signal vga_mem_addr_19 : std_logic_vector(18 downto 0);
signal cam_mem_addr : std_logic_vector(17 downto 0);
signal clk48 : std_logic;
signal mem_data_out : std_logic_vector(15 downto 0); -- SRAMのデータ出力。CMOSカメラのデータを2つ集めたもの。
signal mem_data_oe : std_logic; -- SRAMのmemory data出力のOutput Enable
signal n_mem_data_oe : std_logic;
signal vga_ydata : std_logic_vector(15 downto 0);
signal input_mem_data : std_logic_vector(15 downto 0);
signal cam_clk_node, cam_clk_locked : std_logic;
signal n_cam_clk_node, cam_clk_reset : std_logic;
signal n_mclk : std_logic;
begin
DCM_module_24MHz_inst : DCM_module_24MHz port map(
clk48MHz_in => clk,
clk48_out => clk48,
cam_clk_out => cam_clk_node,
pclk_in => cam_pclk,
mclk_out => mclk,
cam_clk_locked => cam_clk_locked,
mclk_locked => mclk_locked
);
reset <= not mclk_locked;
n_cam_reset <= cam_clk_locked; -- CMOSカメラ用のリセットを出力する
-- CMOSカメラ用クロックの生成
n_cam_clk_node <= not cam_clk_node;
cam_clk_reset <= not cam_clk_locked;
ODDR2_for_cam_clk : ODDR2 generic map(
SRTYPE => "ASYNC"
) port map(
Q => cam_clk,
C0 => cam_clk_node,
C1 => n_cam_clk_node,
CE => '1',
D0 => '1',
D1 => '0',
R => cam_clk_reset,
S => '0'
);
-- DAC用クロックの生成
n_mclk <= not mclk;
ODDR2_for_dac_clk : ODDR2 generic map(
SRTYPE => "ASYNC"
) port map(
Q => dac_clk,
C0 => mclk,
C1 => n_mclk,
CE => '1',
D0 => '1',
D1 => '0',
R => reset,
S => '0'
);
-- CMOSカメラからの入力は一度IOBのFFを通す
process(mclk) begin
if mclk'event and mclk='1' then
if reset='1' then
cam_vsync_1d <= '0';
cam_href_1d <= '0';
cam_ydata_1d <= (others => '0');
cam_vsync_2d <= '0';
cam_href_2d <= '0';
cam_ydata_2d <= (others => '0');
cam_href_3d <= '0';
else
cam_vsync_1d <= cam_vsync;
cam_href_1d <= cam_href;
cam_ydata_1d <= cam_ydata;
cam_vsync_2d <= cam_vsync_1d;
cam_href_2d <= cam_href_1d;
cam_ydata_2d <= cam_ydata_1d;
cam_href_3d <= cam_href_2d;
end if;
end if;
end process;
-- CMOSカメラの書き込みアドレスの生成
synchronizer_inst : synchronizer port map(
clk => mclk,
reset => reset,
cam_vsync_1d => cam_vsync_1d,
cam_href_1d => cam_href_1d,
master_sync => master_sync,
r_w => r_w
);
-- mem_dataの入力FF
process(mclk) begin
if mclk'event and mclk='1' then
if reset='1' then
vga_ydata <= (others => '0');
else
vga_ydata <= input_mem_data;
end if;
end if;
end process;
w_r <= not r_w;
VGA_Display_Controller_inst : VGA_Display_Controller port map(
clk => mclk,
reset => reset,
master_sync => master_sync,
pixel_y_data => vga_ydata,
data_enable => w_r,
h_count_out => open,
v_count_out => open,
red_out => dac_red,
green_out => dac_green,
blue_out => dac_blue,
blank_out => vga_blank,
h_syncx_out => vga_hsync,
v_syncx_out => vga_vsync,
mem_addr => vga_mem_addr_19
);
n_dac_blank <= not vga_blank;
Camera_Controller_inst : Camera_Controller port map(
clk => mclk,
reset => reset,
cam_href_2d => cam_href_2d,
master_sync => master_sync,
mem_addr => cam_mem_addr
);
vga_mem_addr <= vga_mem_addr_19(18 downto 1);
SRAM_Controller_inst : SRAM_Controller port map(
clk => mclk,
clk48 => clk48,
reset => reset,
r_w => r_w,
cam_href_3d => cam_href_3d,
master_sync => master_sync,
cam_mem_addr => cam_mem_addr,
cam_ydata_in => cam_ydata_2d,
vga_mem_addr => vga_mem_addr,
mem_data_out => mem_data_out,
mem_data_oe => mem_data_oe,
n_mem_we => n_mem_we,
n_mem_cs0 => n_mem_cs0,
n_mem_cs1 => n_mem_cs1,
n_mem_cs2 => n_mem_cs2,
n_mem_cs3 => n_mem_cs3,
n_mem_lowerB => n_mem_lowerB,
n_mem_upperB => n_mem_upperB,
mem_addr => mem_addr
);
n_mem_data_oe <= not mem_data_oe;
MEM_DATA_GEN : for i in 15 downto 0 generate
IOBUF_inst : IOBUF port map(
O => input_mem_data(i),
IO => mem_data(i),
I => mem_data_out(i),
T => n_mem_data_oe
);
end generate MEM_DATA_GEN;
n_mem_rd <= not r_w;
end RTL;
entity CamDispCntrl_SRAM is
port (
clk : in std_logic; -- 水晶発振器からの48MHzクロック
cam_vsync : in std_logic; -- CMOSカメラからのVSYNC
cam_href : in std_logic; -- CMOSカメラからのHREF
cam_pclk : in std_logic; -- CMOSカメラからのpclk
cam_ydata : in std_logic_vector(7 downto 0); -- CMOSカメラからのYデータ
-- cam_sio_c : out std_logic; -- CMOSカメラのI2Cクロック
-- cam_sio_d : inout std_logic; -- CMOSカメラのI2Cデータ
cam_clk : out std_logic; -- CMOSカメラのクロック
n_cam_reset : out std_logic; -- CMOSカメラのリセット(Lでリセットの予定)
dac_red : out std_logic_vector(7 downto 0); -- DACへのRED出力
dac_green : out std_logic_vector(7 downto 0); -- DACへのGREEN出力
dac_blue : out std_logic_vector(7 downto 0); -- DACへのBLUE出力
n_dac_blank : out std_logic; -- DACへのアクティブローBLANK
dac_clk : out std_logic; -- DACクロック(24MHz)
vga_vsync : out std_logic; -- VGAのVSYNC
vga_hsync : out std_logic; -- VGAのHSYNC
mem_data : inout std_logic_vector(15 downto 0); -- SRAMのmemory data
n_mem_we : out std_logic; -- SRAMのmemory write enable
n_mem_rd : out std_logic; -- SRAMのmemory read enable
n_mem_cs0 : out std_logic; -- SRAMのchip select 0
n_mem_cs1 : out std_logic; -- SRAMのchip select 1
n_mem_cs2 : out std_logic; -- SRAMのchip select 2
n_mem_cs3 : out std_logic; -- SRAMのchip select 3
n_mem_lowerB : out std_logic; -- SRAMのmemory lower byte enable
n_mem_upperB : out std_logic; -- SRAMのmemory upper byte enable
mem_addr : out std_logic_vector(17 downto 0) -- SRAMのmemory address
);
end CamDispCntrl_SRAM;
-- OV7640_Model.vhd-- 現在のOV7640の仕様機能のみをモデル化する
-- Yデータは0から+1していく。UデータはFFから2つずつ減算(つまりずっと奇数)、VデータはFEから2つずつ減算(つまりずっと偶数)
-- clkに対してpclkは5ns程度遅延させる
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity OV7640_Model is
port(
clk : in std_logic; -- クロック入力
n_reset : in std_logic; -- リセット入力
vsync : out std_logic;
href : out std_logic;
pclk : out std_logic;
ydata : out std_logic_vector(7 downto 0)
-- sio_c : in std_logic;
-- sio_d : inout std_logic
);
end OV7640_Model;
architecture BEHAVIOR of OV7640_Model is
constant H_ACTIVE_VIDEO : integer := 640;
constant H_BLANK_SPACE : integer := 124;
constant H_SUM : integer := H_ACTIVE_VIDEO + H_BLANK_SPACE;
constant V_ACTIVE_VIDEO : integer := 480;
constant V_FRONT_PORCH : integer := 31;
constant V_SYNC_PULSE : integer := 3;
constant V_BACK_PORCH : integer := 11;
constant V_SUM : integer := V_ACTIVE_VIDEO + V_FRONT_PORCH + V_SYNC_PULSE + V_BACK_PORCH;
signal h_count : unsigned(10 downto 0); -- 水平カウンタ
signal v_count : unsigned(9 downto 0); -- 垂直カウンタ
signal u_data : unsigned(7 downto 0);
signal v_data : unsigned(7 downto 0);
signal y_data : unsigned(7 downto 0);
signal reset : std_logic;
signal vsync_node : std_logic;
signal ydata_node : std_logic_vector(7 downto 0);
signal pclock : std_logic;
signal href_node : std_logic;
begin
reset <= not n_reset;
pclock <= transport clk after 5 ns;
pclk <= pclock;
-- 水平タイミング生成
process(reset, pclock) begin
if reset='1' then
h_count <= (others => '0');
elsif pclock'event and pclock='1' then
if h_count(10 downto 1) < H_SUM-1 then
h_count <= h_count + 1;
else -- CMOSカメラはUYなどと2クロックで1画素のため
h_count <= (others => '0');
end if;
end if;
end process;
href_node <= '1' when h_count<H_ACTIVE_VIDEO and v_count<V_ACTIVE_VIDEO else '0';
href <= href_node after 1 ns;
-- 垂直タイミング
process(reset, pclock) begin
if reset='1' then
v_count <= unsigned(CONV_STD_LOGIC_VECTOR((V_ACTIVE_VIDEO + V_FRONT_PORCH)-1,10));
elsif pclock'event and pclock='1' then
if h_count(10 downto 0)=H_SUM-1 then
if v_count < V_SUM-1 then
v_count <= v_count + 1;
else
v_count <= (others => '0');
end if;
end if;
end if;
end process;
-- vsync の出力タイミング
process(v_count) begin
if v_count>=(V_ACTIVE_VIDEO + V_FRONT_PORCH)-1 then
if v_count<V_ACTIVE_VIDEO + V_FRONT_PORCH + V_SYNC_PULSE then
vsync_node <= '1';
else
vsync_node <= '0';
end if;
else
vsync_node <= '0';
end if;
end process;
vsync <= vsync_node after 1 ns;
-- ydata の出力
process(reset, pclock) begin -- Yデータ
if reset='1' then
y_data <= (others => '0');
elsif pclock'event and pclock='1' then
if h_count(10 downto 1)<H_ACTIVE_VIDEO and h_count(0)='1' then -- 水平の表示区間で2クロックに1回カウントアップ
y_data <= y_data + 1;
elsif h_count=0 and v_count=0 then -- 1フレーム描画の最初にリセット
y_data <= (others => '0');
end if;
end if;
end process;
process(reset, pclock) begin -- Uデータ
if reset='1' then
u_data <= (others => '1');
elsif pclock'event and pclock='1' then
if h_count(10 downto 1)<H_ACTIVE_VIDEO and h_count(1 downto 0)=0 then -- 水平の表示区間で4クロックに1回-2
u_data <= u_data - 2;
elsif h_count=0 and v_count=0 then -- 1フレーム描画の最初にリセット
u_data <= (others => '1');
end if;
end if;
end process;
process(reset, pclock) begin -- Vデータ
if reset='1' then
v_data <= X"FE";
elsif pclock'event and pclock='1' then
if h_count(10 downto 1)<H_ACTIVE_VIDEO and h_count(1 downto 0)=2 then -- 水平の表示区間で4クロックに1回-2
v_data <= v_data - 2;
elsif h_count=0 and v_count=0 then -- 1フレーム描画の最初にリセット
v_data <= X"FE";
end if;
end if;
end process;
process(h_count, y_data, u_data, v_data) begin
if h_count(10 downto 1)<H_ACTIVE_VIDEO then -- 表示区間
case h_count(1 downto 0) is
when "00" =>
ydata_node <= std_logic_vector(u_data);
when "01" =>
ydata_node <= std_logic_vector(y_data);
when "10" =>
ydata_node <= std_logic_vector(v_data);
when others => -- "11"
ydata_node <= std_logic_vector(y_data);
end case;
else
ydata_node <= (others => '0');
end if;
end process;
ydata <= ydata_node after 1 ns;
end BEHAVIOR;
-- IS61LV25616_model.vhd
--
-- IS61LV25616のモデル。タイミング関係は全く考慮せずに動作だけをモデル化する
-- 256KB入れると厳しいので、1/4にした
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
library modelsim_lib;
use modelsim_lib.util.all;
entity IS61LV25616 is
port(
mem_data : inout std_logic_vector(15 downto 0); -- SRAMのmemory data
n_mem_we : in std_logic; -- SRAMのmemory write enable
n_mem_rd : in std_logic; -- SRAMのmemory read enable
n_mem_cs : in std_logic; -- SRAMのchip select 0
n_mem_lowerB : in std_logic; -- SRAMのmemory lower byte enable
n_mem_upperB : in std_logic; -- SRAMのmemory upper byte enable
mem_addr : in std_logic_vector(17 downto 0) -- SRAMのmemory address
);
end IS61LV25616;
architecture RTL of IS61LV25616 is
type SRAM256K is array (0 to 65535) of bit_vector(7 downto 0);
signal sram_upper : SRAM256K;
signal sram_lower : SRAM256K;
signal mem_addr_int : integer range 0 to 65535;
signal mem_data_node : std_logic_vector(15 downto 0);
signal mem_data_node2 : std_logic_vector(15 downto 0);
signal master_sync : std_logic;
begin
mem_addr_int <= CONV_INTEGER(mem_addr(15 downto 0));
-- Write Upper
process(n_mem_we, n_mem_cs, n_mem_upperB, mem_data, mem_addr_int) begin
if n_mem_we='0' and n_mem_cs='0' and n_mem_upperB='0' then
sram_upper(mem_addr_int) <= To_bitvector(mem_data(15 downto 8));
end if;
end process;
-- Write Lower
process(n_mem_we, n_mem_cs, n_mem_lowerB, mem_data, mem_addr_int) begin
if n_mem_we='0' and n_mem_cs='0' and n_mem_lowerB='0' then
sram_lower(mem_addr_int) <= To_bitvector(mem_data(7 downto 0));
end if;
end process;
-- -- Read Upper
-- process(n_mem_cs, n_mem_rd, n_mem_upperB, mem_addr_int) begin
-- if n_mem_cs='0' and n_mem_rd='0' and n_mem_upperB='0' then
-- mem_data_node(15 downto 8) <= To_stdlogicvector(sram_upper(mem_addr_int));
-- else
-- mem_data_node(15 downto 8) <= (others => 'Z');
-- end if;
-- end process;
-- -- Read Lower
-- process(n_mem_cs, n_mem_rd, n_mem_lowerB, mem_addr_int) begin
-- if n_mem_cs='0' and n_mem_rd='0' and n_mem_lowerB='0' then
-- mem_data_node(7 downto 0) <= To_stdlogicvector(sram_lower(mem_addr_int));
-- else
-- mem_data_node(7 downto 0) <= (others => 'Z');
-- end if;
-- end process;
-- init_signal_spy でIS61LV25616_instの下にmaster_syncを持ってくる
process begin
init_signal_spy("../camdispcntrl_sram_inst/master_sync", "master_sync", 1, -1);
wait;
end process;
-- データの流れを見やすいように上位のデータは55から+1, 下位のデータはAAから+1して、出力
process(master_sync, n_mem_we) begin -- Read Upper
if master_sync='1' then
mem_data_node2(15 downto 8) <= x"55";
elsif n_mem_we'event and n_mem_we='1' then
if n_mem_cs='0' and n_mem_upperB='0' then
mem_data_node2(15 downto 8) <= mem_data_node2(15 downto 8) + 1;
end if;
end if;
end process;
mem_data_node(15 downto 8) <= mem_data_node2(15 downto 8) when n_mem_cs='0' and n_mem_rd='0' and n_mem_upperB='0' else (others => 'Z');
process(master_sync, n_mem_we) begin -- Read Lower
if master_sync='1' then
mem_data_node2(7 downto 0) <= x"AA";
elsif n_mem_we'event and n_mem_we='1' then
if n_mem_cs='0' and n_mem_lowerB='0' then
mem_data_node2(7 downto 0) <= mem_data_node2(7 downto 0) + 1;
end if;
end if;
end process;
mem_data_node(7 downto 0) <= mem_data_node2(7 downto 0) when n_mem_cs='0' and n_mem_rd='0' and n_mem_lowerB='0' else (others => 'Z');
mem_data <= mem_data_node after 1 ns;
end RTL;
-- Read Upper
process(n_mem_cs, n_mem_rd, n_mem_upperB, mem_addr_int) begin
if n_mem_cs='0' and n_mem_rd='0' and n_mem_upperB='0' then
mem_data_node(15 downto 8) <= To_stdlogicvector(sram_upper(mem_addr_int));
else
mem_data_node(15 downto 8) <= (others => 'Z');
end if;
end process;
-- Read Lower
process(n_mem_cs, n_mem_rd, n_mem_lowerB, mem_addr_int) begin
if n_mem_cs='0' and n_mem_rd='0' and n_mem_lowerB='0' then
mem_data_node(7 downto 0) <= To_stdlogicvector(sram_lower(mem_addr_int));
else
mem_data_node(7 downto 0) <= (others => 'Z');
end if;
end process;
-- データの流れを見やすいように上位のデータは55から+1, 下位のデータはAAから+1して、出力 process(master_sync, n_mem_we) begin -- Read Upper
if master_sync='1' then
mem_data_node2(15 downto 8) <= x"55";
elsif n_mem_we'event and n_mem_we='1' then
if n_mem_cs='0' and n_mem_rd='0' and n_mem_upperB='0' then
mem_data_node2(15 downto 8) <= mem_data_node2(15 downto 8) + 1;
end if;
end if;
end process;
mem_data_node(15 downto 8) <= mem_data_node2(15 downto 8) when n_mem_cs='0' and n_mem_rd='0' and n_mem_upperB='0' else (others => 'Z');
process(master_sync, n_mem_we) begin -- Read Lower
if master_sync='1' then
mem_data_node2(7 downto 0) <= x"AA";
elsif n_mem_we'event and n_mem_we='1' then
if n_mem_cs='0' and n_mem_rd='0' and n_mem_lowerB='0' then
mem_data_node2(7 downto 0) <= mem_data_node2(7 downto 0) + 1;
end if;
end if;
end process;
mem_data_node(7 downto 0) <= mem_data_node2(7 downto 0) when n_mem_cs='0' and n_mem_rd='0' and n_mem_lowerB='0' else (others => 'Z');
library modelsim_lib;
use modelsim_lib.util.all;
-- init_signal_spy でIS61LV25616_instの下にmaster_syncを持ってくる
process begin
init_signal_spy("../camdispcntrl_sram_inst/master_sync", "master_sync", 1, -1);
wait;
end process;
-- init_signal_spy でIS61LV25616_instの下にmaster_syncを持ってくる
process begin
init_signal_spy("/testbench/camdispcntrl_sram_inst/master_sync", "/testbench/is61lv25616_inst/master_sync", 1, -1);
wait;
end process;
MEM_DATA_GEN : for i in 15 downto 0 generate
IOBUF_inst : IOBUF port map(
O => input_mem_data(i),
IO => mem_data(i),
I => mem_data_out(i),
T => n_mem_data_oe
);
end generate MEM_DATA_GEN;
-- pragma translate_off
library UNISIM;
use UNISIM.VComponents.all;
-- pragma translate_on
-- 慣性遅延と伝搬遅延の比較
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
entity delay_test is
end delay_test;
architecture testbanch of delay_test is
signal clk : std_logic := '1';
signal delayed_clk : std_logic;
begin
clk <= not clk after 10 ns;
delayed_clk <= clk after 5 ns; -- 慣性遅延
end;
をdelayed_clk <= clk after 5 ns; -- 慣性遅延
に変更した時の波形を下に示す。delayed_clk <= clk after 10 ns; -- 慣性遅延
に変更した時の波形を下に示す。delayed_clk <= clk after 10.1 ns; -- 慣性遅延
にVHDLソースを変更する。delayed_clk <= transport clk after 10.1 ns; -- 伝搬遅延
としても問題ない。delayed_clk <= transport clk after 15 ns; -- 伝搬遅延
NET "cam_clk" OFFSET = OUT 10 ns AFTER "clk" RISING;
NET "cam_clk" OFFSET = OUT 10 ns AFTER "clk" FALLING;
NET "dac_blue<0>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<1>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<2>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<3>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<4>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<5>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<6>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_blue<7>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<0>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<1>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<2>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<3>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<4>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<5>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<6>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_green<7>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<0>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<1>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<2>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<3>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<4>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<5>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<6>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "dac_red<7>" OFFSET = OUT 40.66 ns AFTER "cam_pclk";
NET "mem_addr<0>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<1>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<2>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<3>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<4>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<5>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<6>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<7>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<8>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<9>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<10>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<11>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<12>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<13>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<14>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<15>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<16>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_addr<17>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<0>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<1>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<2>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<3>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<4>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<5>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<6>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<7>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<8>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<9>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<10>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<11>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<12>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<13>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<14>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "mem_data<15>" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "n_mem_lowerB" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "n_mem_upperB" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "n_mem_rd" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "n_mem_we" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "vga_hsync" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "vga_vsync" OFFSET = OUT 10 ns AFTER "cam_pclk";
NET "clk" TNM_NET = clk;
TIMESPEC TS_clk = PERIOD "clk" 20.83 ns HIGH 50%;
NET "cam_pclk" TNM_NET = cam_pclk;
TIMESPEC TS_cam_pclk = PERIOD "cam_pclk" 41.66 ns HIGH 50%;
NET "cam_href" OFFSET = IN 15.83 ns VALID 36.66 ns BEFORE "cam_pclk" RISING;
NET "cam_vsync" OFFSET = IN 15.83 ns VALID 36.66 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<0>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "clk" TNM_NET = clk;
TIMESPEC TS_clk = PERIOD "clk" 20.83 ns HIGH 50%;
NET "cam_pclk" TNM_NET = cam_pclk;
TIMESPEC TS_cam_pclk = PERIOD "cam_pclk" 41.66 ns HIGH 50%;
NET "cam_href" OFFSET = IN 15.83 ns VALID 36.66 ns BEFORE "cam_pclk" RISING;
NET "cam_vsync" OFFSET = IN 15.83 ns VALID 36.66 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<0>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<1>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<2>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<3>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<4>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<5>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<6>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "cam_ydata<7>" OFFSET = IN 15 ns VALID 23 ns BEFORE "cam_pclk" RISING;
NET "mem_data<0>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<1>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<2>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<3>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<4>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<5>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<6>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<7>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<8>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<9>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<10>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<11>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<12>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<13>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<14>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
NET "mem_data<15>" OFFSET = IN 21.66 ns VALID 24.66 ns BEFORE "cam_pclk" RISING;
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | - | - | - | 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 |