-----------------------------------------------------------------------------
--
-- AXI Slave
--
-----------------------------------------------------------------------------
-- 2012/02/25 : S_AXI_AWBURST=1 (INCR) にのみ対応、AWSIZE, ARSIZE = 000 (1byte), 001 (2bytes), 010 (4bytes) のみ対応。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
--library unisim;
--use unisim.vcomponents.all;
entity cdc_axi_slave is
generic (
C_S_AXI_ID_WIDTH : integer := 1;
C_S_AXI_ADDR_WIDTH : integer := 32;
C_S_AXI_DATA_WIDTH : integer := 32;
C_S_AXI_AWUSER_WIDTH : integer := 1;
C_S_AXI_ARUSER_WIDTH : integer := 1;
C_S_AXI_WUSER_WIDTH : integer := 1;
C_S_AXI_RUSER_WIDTH : integer := 1;
C_S_AXI_BUSER_WIDTH : integer := 1
);
port(
-- System Signals
ACLK : in std_logic;
ARESETN : in std_logic;
-- Slave Interface Write Address Ports
S_AXI_AWID : in std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0);
S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
S_AXI_AWLEN : in std_logic_vector(8-1 downto 0);
S_AXI_AWSIZE : in std_logic_vector(3-1 downto 0);
S_AXI_AWBURST : in std_logic_vector(2-1 downto 0);
S_AXI_AWLOCK : in std_logic_vector(2-1 downto 0);
S_AXI_AWCACHE : in std_logic_vector(4-1 downto 0);
S_AXI_AWPROT : in std_logic_vector(3-1 downto 0);
S_AXI_AWREGION : in std_logic_vector(4-1 downto 0);
S_AXI_AWQOS : in std_logic_vector(4-1 downto 0);
S_AXI_AWUSER : in std_logic_vector(C_S_AXI_AWUSER_WIDTH-1 downto 0);
S_AXI_AWVALID : in std_logic;
S_AXI_AWREADY : out std_logic;
-- Slave Interface Write Data Ports
S_AXI_WID : in std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0);
S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
S_AXI_WSTRB : in std_logic_vector(C_S_AXI_DATA_WIDTH/8-1 downto 0);
S_AXI_WLAST : in std_logic;
S_AXI_WUSER : in std_logic_vector(C_S_AXI_WUSER_WIDTH-1 downto 0);
S_AXI_WVALID : in std_logic;
S_AXI_WREADY : out std_logic;
-- Slave Interface Write Response Ports
S_AXI_BID : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0);
S_AXI_BRESP : out std_logic_vector(2-1 downto 0);
S_AXI_BUSER : out std_logic_vector(C_S_AXI_BUSER_WIDTH-1 downto 0);
S_AXI_BVALID : out std_logic;
S_AXI_BREADY : in std_logic;
-- Slave Interface Read Address Ports
S_AXI_ARID : in std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0);
S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
S_AXI_ARLEN : in std_logic_vector(8-1 downto 0);
S_AXI_ARSIZE : in std_logic_vector(3-1 downto 0);
S_AXI_ARBURST : in std_logic_vector(2-1 downto 0);
S_AXI_ARLOCK : in std_logic_vector(2-1 downto 0);
S_AXI_ARCACHE : in std_logic_vector(4-1 downto 0);
S_AXI_ARPROT : in std_logic_vector(3-1 downto 0);
S_AXI_ARREGION : in std_logic_vector(4-1 downto 0);
S_AXI_ARQOS : in std_logic_vector(4-1 downto 0);
S_AXI_ARUSER : in std_logic_vector(C_S_AXI_ARUSER_WIDTH-1 downto 0);
S_AXI_ARVALID : in std_logic;
S_AXI_ARREADY : out std_logic;
-- Slave Interface Read Data Ports
S_AXI_RID : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0);
S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
S_AXI_RRESP : out std_logic_vector(2-1 downto 0);
S_AXI_RLAST : out std_logic;
S_AXI_RUSER : out std_logic_vector(C_S_AXI_RUSER_WIDTH-1 downto 0);
S_AXI_RVALID : out std_logic;
S_AXI_RREADY : in std_logic;
-- TMDS Signals
pixclk : in std_logic;
TMDS_tx_clk_p : out std_logic; -- Clock
TMDS_tx_clk_n : out std_logic;
TMDS_tx_2_G_p : out std_logic; -- Green
TMDS_tx_2_G_n : out std_logic;
TMDS_tx_1_R_p : out std_logic; -- Red
TMDS_tx_1_R_n : out std_logic;
TMDS_tx_0_B_p : out std_logic; -- Blue
TMDS_tx_0_B_n : out std_logic
);
end cdc_axi_slave;
architecture implementation of cdc_axi_slave is
component dvi_disp
generic (
PLL_CLKFBOUT_MULT : integer := 20; -- VGA解像度 PLL VCO Freq 400MHz ~ 1000MHz
PLL_CLKIN_PERIOD : real := 40.0; -- VGA ピクセルクロック周期
PLL_CLKOUT0_DIVIDE : integer := 2; -- ピクセルクロックX10
PLL_CLKOUT1_DIVIDE : integer := 20; -- ピクセルクロック
PLL_CLKOUT2_DIVIDE : integer := 10 -- ピクセルクロックX2
);
port (
pixclk : in std_logic; -- pixel clock
reset_in : in std_logic; -- active high
red_in : in std_logic_vector(7 downto 0); -- RED入力
green_in : in std_logic_vector(7 downto 0); -- GREEN入力
blue_in : in std_logic_vector(7 downto 0); -- BLUE入力
hsync : in std_logic;
vsync : in std_logic;
display_enable : in std_logic; -- 表示が有効
TMDS_tx_clk_p : out std_logic; -- Clock
TMDS_tx_clk_n : out std_logic;
TMDS_tx_2_G_p : out std_logic; -- Green
TMDS_tx_2_G_n : out std_logic;
TMDS_tx_1_R_p : out std_logic; -- Red
TMDS_tx_1_R_n : out std_logic;
TMDS_tx_0_B_p : out std_logic; -- Blue
TMDS_tx_0_B_n : out std_logic
);
end component;
component CharDispCtrler
port(
axi4clk : in std_logic;
pixclk : in std_logic;
reset : in std_logic;
processor_addr : in std_logic_vector(12 downto 0);
processor_din : in std_logic_vector(15 downto 0);
processor_dout : out std_logic_vector(15 downto 0);
processor_we : in std_logic;
VGA_RED : out std_logic_vector(2 downto 0);
VGA_GREEN : out std_logic_vector(2 downto 0);
VGA_BLUE : out std_logic_vector(2 downto 0);
VGA_HSYNC : out std_logic;
VGA_VSYNC : out std_logic;
display_enable : out std_logic
);
end component;
COMPONENT afifo_sm
PORT (
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
dout : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
full : OUT STD_LOGIC;
almost_full : OUT STD_LOGIC;
overflow : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
almost_empty : OUT STD_LOGIC;
underflow : OUT STD_LOGIC
);
END COMPONENT;
constant AxBURST_FIXED : std_logic_vector := "00";
constant AxBURST_INCR : std_logic_vector := "01";
constant AxBURST_WRAP : std_logic_vector := "10";
constant RESP_OKAY : std_logic_vector := "00";
constant RESP_EXOKAY : std_logic_vector := "01";
constant RESP_SLVERR : std_logic_vector := "10";
constant RESP_DECERR : std_logic_vector := "11";
-- for write transaction
type write_transaction_state is (idle_wr, awr_wait, awr_accept, wr_burst);
type write_response_state is (idle_wres, bvalid_assert);
type write_wready_state is (idle_wrdy, wready_assert);
signal wrt_cs : write_transaction_state;
signal wrres : write_response_state;
signal wrwr : write_wready_state;
-- for read transaction
type read_transaction_state is (idle_rd, arr_wait, arr_accept, rd_burst);
type read_last_state is (idle_rlast, rlast_assert);
signal rdt_cs : read_transaction_state;
signal rdlast : read_last_state;
signal reset_1d, reset_2d, reset : std_logic := '1';
signal awready : std_logic;
signal wr_addr : std_logic_vector(12 downto 0);
signal wr_bid : std_logic_vector(0 downto 0);
signal wr_bresp : std_logic_vector(1 downto 0);
signal wr_bvalid : std_logic;
signal arready : std_logic;
signal rd_addr : std_logic_vector(12 downto 0);
signal rd_axi_count : std_logic_vector(7 downto 0);
signal rd_cdc_count : std_logic_vector(8 downto 0);
signal rdfifo_din : std_logic_vector(15 downto 0);
signal rdfifo_wr_en : std_logic;
signal rdfifo_rd_en : std_logic;
signal rdfifo_full, rdfifo_empty : std_logic;
signal rdfifo_almost_full, rdfifo_almost_empty : std_logic;
signal rdfifo_overflow, rdfifo_underflow : std_logic;
signal rvalid : std_logic;
signal rlast : std_logic;
signal cdc_addr : std_logic_vector(12 downto 0);
signal vga_red, vga_green, vga_blue : std_logic_vector(2 downto 0);
signal vga_red8, vga_green8, vga_blue8 : std_logic_vector(7 downto 0);
signal vga_hsync, vga_vsync : std_logic;
signal display_enable : std_logic;
signal cdc_we : std_logic;
signal rdfifo_wr_en_node : std_logic;
begin
-- ARESETN をACLK で同期化
process (ACLK) begin
if ACLK'event and ACLK='1' then
reset_1d <= not ARESETN;
reset_2d <= reset_1d;
end if;
end process;
reset <= reset_2d;
-- AXI4バス Write Transaction State Machine
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wrt_cs <= idle_wr;
awready <= '0';
else
case (wrt_cs) is
when idle_wr =>
if S_AXI_AWVALID='1' then -- S_AXI_AWVALID が1にアサートされた
if rdt_cs=idle_rd then -- Read Transaction が終了している(Writeの方が優先順位が高い)
wrt_cs <= awr_accept;
awready <= '1';
else -- Read Transaction が終了していないのでWait
wrt_cs <= awr_wait;
end if;
end if;
when awr_wait => -- Read Transaction の終了待ち
if rdt_cs=idle_rd or rdt_cs=arr_wait then -- Read Transaction が終了
wrt_cs <= awr_accept;
awready <= '1';
end if;
when awr_accept => -- S_AXI_AWREADY をアサート
wrt_cs <= wr_burst;
awready <= '0';
when wr_burst => -- Writeデータの転送
if S_AXI_WLAST='1' and S_AXI_WVALID='1' then -- Write Transaction 終了
wrt_cs <= idle_wr;
end if;
end case;
end if;
end if;
end process;
S_AXI_AWREADY <= awready;
S_AXI_WREADY <= '1' when wrt_cs=wr_burst else '0';
cdc_we <= '1' when wrt_cs=wr_burst and S_AXI_WVALID='1' else '0';
-- wr_addr の処理
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wr_addr <= (others => '0');
else
if wrt_cs=awr_accept then
wr_addr <= S_AXI_AWADDR(14 downto 2); -- 32ビット幅データのため
elsif wrt_cs=wr_burst and S_AXI_WVALID='1' then -- アドレスを1つ進める
wr_addr <= wr_addr + 1;
end if;
end if;
end if;
end process;
-- wr_bid の処理
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wr_bid <= "0";
else
if wrt_cs=awr_accept then
wr_bid <= S_AXI_AWID;
end if;
end if;
end if;
end process;
S_AXI_BID <= wr_bid;
-- wr_bresp の処理
-- S_AXI_AWBURSTがINCRの時はOKAYを返す。それ以外はSLVERRを返す。
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wr_bresp <= (others => '0');
else
if wrt_cs=awr_accept then
if S_AXI_AWBURST=AxBURST_INCR then -- バーストタイプがアドレス・インクリメントタイプ
wr_bresp <= RESP_OKAY; -- Write Transaction は成功
else
wr_bresp <= RESP_SLVERR; -- エラー
end if;
end if;
end if;
end if;
end process;
S_AXI_BRESP <= wr_bresp;
-- wr_bvalid の処理
-- Write Transaction State Machineには含まない。axi_master のシミュレーションを見ると1クロックで終了しているので、長い間、Master側の都合でWaitしていることは考えない。
-- 次のWrite転送まで遅延しているようであれば、Write Transaction State Machine に入れてブロックすることも考える必要がある。
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
wr_bvalid <= '0';
else
if S_AXI_WLAST='1' and S_AXI_WVALID='1' then -- Write Transaction 終了
wr_bvalid <= '1';
elsif wr_bvalid='1' and S_AXI_BREADY='1' then -- wr_bvalid が1でMaster側のReadyも1ならばWrite resonse channel の転送も終了
wr_bvalid <= '0';
end if;
end if;
end if;
end process;
S_AXI_BVALID <= wr_bvalid;
S_AXI_BUSER <= (others => '0');
-- AXI4バス Read Transaction State Machine
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
rdt_cs <= idle_rd;
arready <= '0';
else
case (rdt_cs) is
when idle_rd =>
if S_AXI_ARVALID='1' then -- Read Transaction 要求
if wrt_cs=idle_wr and S_AXI_AWVALID='0' then -- Write Transaction State Machine がidle でWrite要求もない
rdt_cs <= arr_accept;
arready <= '1';
else -- Write Transaction が終了していないのでWait
rdt_cs <= arr_wait;
end if;
end if;
when arr_wait => -- Write Transaction の終了待ち
if wrt_cs=idle_wr and S_AXI_AWVALID='0' then -- Write Transaction State Machine がidle でWrite要求もない
rdt_cs <= arr_accept;
arready <= '1';
end if;
when arr_accept => -- S_AXI_ARREADY をアサート
rdt_cs <= rd_burst;
arready <= '0';
when rd_burst => -- Readデータの転送
if rd_axi_count=0 and rvalid='1' and S_AXI_RREADY='1' then -- Read Transaction 終了
rdt_cs <= idle_rd;
end if;
end case;
end if;
end if;
end process;
S_AXI_ARREADY <= arready;
-- rd_addr の処理
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
rd_addr <= (others => '0');
else
if rdt_cs=arr_accept then
rd_addr <= S_AXI_ARADDR(14 downto 2); -- 32ビット幅データのため
elsif rdt_cs=rd_burst and rdfifo_almost_full='0' and rd_cdc_count/=0 then -- rdfifoに余裕があるときにはアドレスを1つ進める
rd_addr <= rd_addr + 1;
end if;
end if;
end if;
end process;
-- Read用FIFOのインスタンス
rdfifo : afifo_sm PORT MAP (
clk => ACLK,
rst => reset,
din => rdfifo_din,
wr_en => rdfifo_wr_en,
rd_en => rdfifo_rd_en,
dout => S_AXI_RDATA(15 downto 0),
full => rdfifo_full,
almost_full => rdfifo_almost_full,
overflow => rdfifo_overflow,
empty => rdfifo_empty,
almost_empty => rdfifo_almost_empty,
underflow => rdfifo_underflow
);
S_AXI_RDATA(31 downto 16) <= (others => '0');
rvalid <= not rdfifo_empty;
S_AXI_RVALID <= rvalid;
rdfifo_wr_en_node <= '1' when rdt_cs=rd_burst and rdfifo_almost_full='0' and rd_cdc_count/=0 else '0';
-- BlockRAMのReadは1クロック遅延するため、1クロック遅延させる。
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
rdfifo_wr_en <= '0';
else
rdfifo_wr_en <= rdfifo_wr_en_node;
end if;
end if;
end process;
rdfifo_rd_en <= '1' when rdt_cs=rd_burst and rvalid='1' and S_AXI_RREADY='1' else '0';
-- rd_cdc_count の処理(CDC側のデータカウント)
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
rd_cdc_count <= (others => '0');
else
if rdt_cs=arr_accept then -- ロード
rd_cdc_count <= ('0'& S_AXI_ARLEN) + 1;
elsif rdt_cs=rd_burst and rdfifo_almost_full='0' and rd_cdc_count/=0 then -- FIFOに余裕がある
rd_cdc_count <= rd_cdc_count - 1;
end if;
end if;
end if;
end process;
-- rd_axi_count の処理(AXIバス側のデータカウント)
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
rd_axi_count <= (others => '0');
else
if rdt_cs=arr_accept then -- rd_axi_count のロード
rd_axi_count <= S_AXI_ARLEN;
elsif rdt_cs=rd_burst and rvalid='1' and S_AXI_RREADY='1' then -- Read Transaction が1つ終了
rd_axi_count <= rd_axi_count - 1;
end if;
end if;
end if;
end process;
-- rdlast State Machine
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
rdlast <= idle_rlast;
rlast <= '0';
else
case (rdlast) is
when idle_rlast =>
if rd_axi_count=1 and rvalid='1' and S_AXI_RREADY='1' then -- バーストする場合
rdlast <= rlast_assert;
rlast <= '1';
elsif rdt_cs=arr_accept and S_AXI_ARLEN=0 then -- 転送数が1の場合
rdlast <= rlast_assert;
rlast <= '1';
end if;
when rlast_assert =>
if rvalid='1' and S_AXI_RREADY='1' then -- Read Transaction 終了(rd_axi_count=0は決定)
rdlast <= idle_rlast;
rlast <= '0';
end if;
end case;
end if;
end if;
end process;
S_AXI_RLAST <= rlast;
-- S_AXI_RID, S_AXI_RUSER の処理
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
S_AXI_RID <= (others => '0');
else
if rdt_cs=arr_accept then
S_AXI_RID <= S_AXI_ARID;
end if;
end if;
end if;
end process;
S_AXI_RUSER <= (others => '0');
-- S_AXI_RRESP は、S_AXI_ARBURST がINCR の場合はOKAYを返す。それ以外はSLVERRを返す。
process (ACLK) begin
if ACLK'event and ACLK='1' then
if reset='1' then
S_AXI_RRESP <= (others => '0');
else
if rdt_cs=arr_accept then
if S_AXI_ARBURST=AxBURST_INCR then
S_AXI_RRESP <= RESP_OKAY;
else
S_AXI_RRESP <= RESP_SLVERR;
end if;
end if;
end if;
end if;
end process;
-- CharDispCtrler
cdc_addr <= wr_addr when rdt_cs=idle_rd or rdt_cs=arr_wait else rd_addr;
CDC_inst : CharDispCtrler port map (
axi4clk => ACLK,
pixclk => pixclk,
reset => reset,
processor_addr => cdc_addr,
processor_din => S_AXI_WDATA(15 downto 0),
processor_dout => rdfifo_din,
processor_we => cdc_we,
VGA_RED => vga_red,
VGA_GREEN => vga_green,
VGA_BLUE => vga_blue,
VGA_HSYNC => vga_hsync,
VGA_VSYNC => vga_vsync,
display_enable => display_enable
);
-- dvi_disp
-- VGA解像度 PLL VCO Freq=400MHz ~ 1000MHz なので、25MHz入力クロックだと最初に20倍する必要がある。
-- XGA 解像度だと、PLL_CLKFBOUT_MULT=20だと、PLL VCO Freq=1300MHzとなり、1000MHzを超えるので、10倍に変更する。
dvi_disp_inst : dvi_disp generic map (
-- PLL_CLKFBOUT_MULT => 20, -- VGA
-- PLL_CLKIN_PERIOD => 40.0,
-- PLL_CLKOUT0_DIVIDE => 2,
-- PLL_CLKOUT1_DIVIDE => 20,
-- PLL_CLKOUT2_DIVIDE => 10
PLL_CLKFBOUT_MULT => 20, -- SVGA
PLL_CLKIN_PERIOD => 25.0,
PLL_CLKOUT0_DIVIDE => 2,
PLL_CLKOUT1_DIVIDE => 20,
PLL_CLKOUT2_DIVIDE => 10
-- PLL_CLKFBOUT_MULT => 10, -- XGA
-- PLL_CLKIN_PERIOD => 15.4,
-- PLL_CLKOUT0_DIVIDE => 1,
-- PLL_CLKOUT1_DIVIDE => 10,
-- PLL_CLKOUT2_DIVIDE => 5
-- PLL_CLKFBOUT_MULT => 10, -- SXGA(-3スピードグレードのみ)
-- PLL_CLKIN_PERIOD => 9.3,
-- PLL_CLKOUT0_DIVIDE => 1,
-- PLL_CLKOUT1_DIVIDE => 10,
-- PLL_CLKOUT2_DIVIDE => 5
) port map (
pixclk => pixclk,
reset_in => reset,
red_in => vga_red8,
green_in => vga_green8,
blue_in => vga_blue8,
hsync => vga_hsync,
vsync => vga_vsync,
display_enable => display_enable,
TMDS_tx_clk_p => TMDS_tx_clk_p,
TMDS_tx_clk_n => TMDS_tx_clk_n,
TMDS_tx_2_G_p => TMDS_tx_2_G_p,
TMDS_tx_2_G_n => TMDS_tx_2_G_n,
TMDS_tx_1_R_p => TMDS_tx_1_R_p,
TMDS_tx_1_R_n => TMDS_tx_1_R_n,
TMDS_tx_0_B_p => TMDS_tx_0_B_p,
TMDS_tx_0_B_n => TMDS_tx_0_B_n
);
vga_red8 <= vga_red & "00000";
vga_green8 <= vga_green & "00000";
vga_blue8 <= vga_blue & "00000";
end implementation;
##############################################################
#
# Xilinx Core Generator version 13.4
# Date: Sat Feb 25 06:45:30 2012
#
##############################################################
#
# This file contains the customisation parameters for a
# Xilinx CORE Generator IP GUI. It is strongly recommended
# that you do not manually alter this file as it may cause
# unexpected and unsupported behavior.
#
##############################################################
#
# Generated from component: xilinx.com:ip:fifo_generator:8.4
#
##############################################################
#
# BEGIN Project Options
SET addpads = false
SET asysymbol = true
SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false
SET designentry = VHDL
SET device = xc6slx45
SET devicefamily = spartan6
SET flowvendor = Other
SET formalverification = false
SET foundationsym = false
SET implementationfiletype = Ngc
SET package = csg324
SET removerpms = false
SET simulationfiles = Behavioral
SET speedgrade = -2
SET verilogsim = false
SET vhdlsim = true
# END Project Options
# BEGIN Select
SELECT Fifo_Generator xilinx.com:ip:fifo_generator:8.4
# END Select
# BEGIN Parameters
CSET add_ngc_constraint_axi=false
CSET almost_empty_flag=true
CSET almost_full_flag=true
CSET aruser_width=1
CSET awuser_width=1
CSET axi_address_width=32
CSET axi_data_width=64
CSET axi_type=AXI4_Stream
CSET axis_type=FIFO
CSET buser_width=1
CSET clock_enable_type=Slave_Interface_Clock_Enable
CSET clock_type_axi=Common_Clock
CSET component_name=afifo_sm
CSET data_count=false
CSET data_count_width=5
CSET disable_timing_violations=false
CSET disable_timing_violations_axi=false
CSET dout_reset_value=0
CSET empty_threshold_assert_value=4
CSET empty_threshold_assert_value_axis=1022
CSET empty_threshold_assert_value_rach=1022
CSET empty_threshold_assert_value_rdch=1022
CSET empty_threshold_assert_value_wach=1022
CSET empty_threshold_assert_value_wdch=1022
CSET empty_threshold_assert_value_wrch=1022
CSET empty_threshold_negate_value=5
CSET enable_aruser=false
CSET enable_awuser=false
CSET enable_buser=false
CSET enable_common_overflow=false
CSET enable_common_underflow=false
CSET enable_data_counts_axis=false
CSET enable_data_counts_rach=false
CSET enable_data_counts_rdch=false
CSET enable_data_counts_wach=false
CSET enable_data_counts_wdch=false
CSET enable_data_counts_wrch=false
CSET enable_ecc=false
CSET enable_ecc_axis=false
CSET enable_ecc_rach=false
CSET enable_ecc_rdch=false
CSET enable_ecc_wach=false
CSET enable_ecc_wdch=false
CSET enable_ecc_wrch=false
CSET enable_handshake_flag_options_axis=false
CSET enable_handshake_flag_options_rach=false
CSET enable_handshake_flag_options_rdch=false
CSET enable_handshake_flag_options_wach=false
CSET enable_handshake_flag_options_wdch=false
CSET enable_handshake_flag_options_wrch=false
CSET enable_read_channel=false
CSET enable_read_pointer_increment_by2=false
CSET enable_reset_synchronization=true
CSET enable_ruser=false
CSET enable_tdata=false
CSET enable_tdest=false
CSET enable_tid=false
CSET enable_tkeep=false
CSET enable_tlast=false
CSET enable_tready=true
CSET enable_tstrobe=false
CSET enable_tuser=false
CSET enable_write_channel=false
CSET enable_wuser=false
CSET fifo_application_type_axis=Data_FIFO
CSET fifo_application_type_rach=Data_FIFO
CSET fifo_application_type_rdch=Data_FIFO
CSET fifo_application_type_wach=Data_FIFO
CSET fifo_application_type_wdch=Data_FIFO
CSET fifo_application_type_wrch=Data_FIFO
CSET fifo_implementation=Common_Clock_Distributed_RAM
CSET fifo_implementation_axis=Common_Clock_Block_RAM
CSET fifo_implementation_rach=Common_Clock_Block_RAM
CSET fifo_implementation_rdch=Common_Clock_Block_RAM
CSET fifo_implementation_wach=Common_Clock_Block_RAM
CSET fifo_implementation_wdch=Common_Clock_Block_RAM
CSET fifo_implementation_wrch=Common_Clock_Block_RAM
CSET full_flags_reset_value=1
CSET full_threshold_assert_value=15
CSET full_threshold_assert_value_axis=1023
CSET full_threshold_assert_value_rach=1023
CSET full_threshold_assert_value_rdch=1023
CSET full_threshold_assert_value_wach=1023
CSET full_threshold_assert_value_wdch=1023
CSET full_threshold_assert_value_wrch=1023
CSET full_threshold_negate_value=14
CSET id_width=4
CSET inject_dbit_error=false
CSET inject_dbit_error_axis=false
CSET inject_dbit_error_rach=false
CSET inject_dbit_error_rdch=false
CSET inject_dbit_error_wach=false
CSET inject_dbit_error_wdch=false
CSET inject_dbit_error_wrch=false
CSET inject_sbit_error=false
CSET inject_sbit_error_axis=false
CSET inject_sbit_error_rach=false
CSET inject_sbit_error_rdch=false
CSET inject_sbit_error_wach=false
CSET inject_sbit_error_wdch=false
CSET inject_sbit_error_wrch=false
CSET input_data_width=16
CSET input_depth=16
CSET input_depth_axis=1024
CSET input_depth_rach=16
CSET input_depth_rdch=1024
CSET input_depth_wach=16
CSET input_depth_wdch=1024
CSET input_depth_wrch=16
CSET interface_type=Native
CSET output_data_width=16
CSET output_depth=16
CSET overflow_flag=true
CSET overflow_flag_axi=false
CSET overflow_sense=Active_High
CSET overflow_sense_axi=Active_High
CSET performance_options=First_Word_Fall_Through
CSET programmable_empty_type=No_Programmable_Empty_Threshold
CSET programmable_empty_type_axis=Empty
CSET programmable_empty_type_rach=Empty
CSET programmable_empty_type_rdch=Empty
CSET programmable_empty_type_wach=Empty
CSET programmable_empty_type_wdch=Empty
CSET programmable_empty_type_wrch=Empty
CSET programmable_full_type=No_Programmable_Full_Threshold
CSET programmable_full_type_axis=Full
CSET programmable_full_type_rach=Full
CSET programmable_full_type_rdch=Full
CSET programmable_full_type_wach=Full
CSET programmable_full_type_wdch=Full
CSET programmable_full_type_wrch=Full
CSET rach_type=FIFO
CSET rdch_type=FIFO
CSET read_clock_frequency=1
CSET read_data_count=false
CSET read_data_count_width=5
CSET register_slice_mode_axis=Fully_Registered
CSET register_slice_mode_rach=Fully_Registered
CSET register_slice_mode_rdch=Fully_Registered
CSET register_slice_mode_wach=Fully_Registered
CSET register_slice_mode_wdch=Fully_Registered
CSET register_slice_mode_wrch=Fully_Registered
CSET reset_pin=true
CSET reset_type=Asynchronous_Reset
CSET ruser_width=1
CSET synchronization_stages=2
CSET synchronization_stages_axi=2
CSET tdata_width=64
CSET tdest_width=4
CSET tid_width=8
CSET tkeep_width=4
CSET tstrb_width=4
CSET tuser_width=4
CSET underflow_flag=true
CSET underflow_flag_axi=false
CSET underflow_sense=Active_High
CSET underflow_sense_axi=Active_High
CSET use_clock_enable=false
CSET use_dout_reset=true
CSET use_embedded_registers=false
CSET use_extra_logic=true
CSET valid_flag=false
CSET valid_sense=Active_High
CSET wach_type=FIFO
CSET wdch_type=FIFO
CSET wrch_type=FIFO
CSET write_acknowledge_flag=false
CSET write_acknowledge_sense=Active_High
CSET write_clock_frequency=1
CSET write_data_count=false
CSET write_data_count_width=5
CSET wuser_width=1
# END Parameters
# BEGIN Extra information
MISC pkg_timestamp=2011-10-22T06:08:52Z
# END Extra information
GENERATE
# CRC: 76cfed70
// M sequence test(m_seq_test.v)
`default_nettype none
module m_seq_test(
input wire clk,
input wire reset,
output reg [7:0] mseq8,
output wire [7:0] mseq8_2
);
reg [15:0] mseq16;
function [7:0] mseqf8_0 (input [7:0] din);
reg xor_result;
begin
xor_result = din[7] ^ din[3] ^ din[2] ^ din[1];
mseqf8_0 = {din[6:0], xor_result};
end
endfunction
function [7:0] mseqf8_1 (input [7:0] din);
reg xor_result;
begin
xor_result = din[7] ^ din[4] ^ din[2] ^ din[0];
mseqf8_1 = {din[6:0], xor_result};
end
endfunction
function [15:0] mseqf16 (input [15:0] din);
reg xor_result;
begin
xor_result = din[15] ^ din[12] ^ din[10] ^ din[8] ^ din[7] ^ din[6] ^ din[3] ^ din[2];
mseqf16 = {din[14:0], xor_result};
end
endfunction
always @(posedge clk) begin
if (reset)
mseq8 <= 8'd1;
else
mseq8 <= mseqf8_0(mseq8);
end
always @(posedge clk) begin
if (reset)
mseq16 <= 16'd1;
else
mseq16 <= mseqf16(mseq16);
end
assign mseq8_2 = mseq16[7:0];
endmodule
`default_nettype wire
`default_nettype none
`timescale 1ns / 1ps
module m_seq_test_tb;
// Inputs
reg clk = 1'b0;
reg reset;
wire [7:0] mseq8;
wire [7:0] mseq8_2;
// Instantiate the Unit Under Test (UUT)
m_seq_test uut (
.clk(clk),
.reset(reset),
.mseq8(mseq8),
.mseq8_2(mseq8_2)
);
parameter CLK_PERIOD = 10;
parameter real CLK_DUTY_CYCLE = 0.5;
parameter CLK_OFFSET = 0;
parameter START_STATE = 1'b0;
initial begin
#CLK_OFFSET;
forever begin
clk = START_STATE;
#(CLK_PERIOD-(CLK_PERIOD*CLK_DUTY_CYCLE)) clk = ~START_STATE;
#(CLK_PERIOD*CLK_DUTY_CYCLE);
end
end
// リセットが解除された後から、mseq8の値をクロックが立ち上がるごとにmseq8.txtに書き込む
integer F_HANDLE;
initial F_HANDLE = $fopen("mseq8.txt");
always @(posedge clk) begin
if (~reset) begin
$fdisplay(F_HANDLE, "%b", mseq8);
$fflush(F_HANDLE);
end
end
// リセットが解除された後から、mseq8_2の値をクロックが立ち上がるごとにmseq8_2.txtに書き込む
integer F_HANDLE2;
initial F_HANDLE2 = $fopen("mseq8_2.txt");
always @(posedge clk) begin
if (~reset) begin
$fdisplay(F_HANDLE2, "%b", mseq8_2);
$fflush(F_HANDLE2);
end
end
initial begin
// Initialize Inputs
reset = 1'b1;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
reset = 1'b0;
#660000;
$fclose(F_HANDLE);
$fclose(F_HANDLE2);
$finish;
end
endmodule
`default_nettype wire
00000001
00000010
00000100
00001001
00010011
00100110
01001101
10011011
00110110
01101100
// M sequence test(m_seq_test.v)
`default_nettype none
module m_seq_test(
input wire clk,
input wire reset,
output reg [7:0] mseq8
);
function [7:0] mseqf8_0 (input [7:0] din);
reg xor_result;
begin
xor_result = din[7] ^ din[3] ^ din[2] ^ din[1];
mseqf8_0 = {din[6:0], xor_result};
end
endfunction
function [7:0] mseqf8_1 (input [7:0] din);
reg xor_result;
begin
xor_result = din[7] ^ din[4] ^ din[2] ^ din[0];
mseqf8_1 = {din[6:0], xor_result};
end
endfunction
always @(posedge clk) begin
if (reset)
mseq8 <= 8'd1;
else
mseq8 <= mseqf8_0(mseq8);
end
endmodule
`default_nettype wire
`default_nettype none
`timescale 1ns / 1ps
module m_seq_test_tb;
// Inputs
reg clk = 1'b0;
reg reset;
wire [7:0] mseq8;
// Instantiate the Unit Under Test (UUT)
m_seq_test uut (
.clk(clk),
.reset(reset),
.mseq8(mseq8)
);
parameter CLK_PERIOD = 10;
parameter real CLK_DUTY_CYCLE = 0.5;
parameter CLK_OFFSET = 0;
parameter START_STATE = 1'b0;
initial begin
#CLK_OFFSET;
forever begin
clk = START_STATE;
#(CLK_PERIOD-(CLK_PERIOD*CLK_DUTY_CYCLE)) clk = ~START_STATE;
#(CLK_PERIOD*CLK_DUTY_CYCLE);
end
end
// リセットが解除された後から、mseq8の値をクロックが立ち上がるごとにmseq8.txtに書き込む
integer F_HANDLE;
initial F_HANDLE = $fopen("mseq8.txt");
always @(posedge clk) begin
if (~reset) begin
$fdisplay(F_HANDLE, "%b", mseq8);
$fflush(F_HANDLE);
end
end
initial begin
// Initialize Inputs
reset = 1'b1;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
reset = 1'b0;
#9900;
$fclose(F_HANDLE);
$finish;
end
endmodule
`default_nettype wire
00000001
00000010
00000101
00001011
00010110
00101100
01011000
10110001
01100011
11000111
00000001
00000011
00000111
00001110
00011101
00111011
01110110
11101100
11011000
10110000
・WriteとReadは交互に行うことにする。WriteとReadがオーバーラップする場合はシミュレーションで確かめたので良しとする。
・Write、Readするデータは0x0から0xFFFFまでとする。当然、キャラクタとして表示されない文字コードがあるが、それは良しとする。最初に書き込むデータは0x0として、次に書き込むデータは+1された0x1とする。その後も+1して行って0xFFFFになったら、0x0に戻す。
・1バーストから256バーストまでのバースト長のデータ転送を行う。バースト長はM系列乱数ジェネレータで生成する。
・Readでは、Writeと同じデータを読み出せることを確認する。データが正しい場合はOKのLEDを点灯する。データが間違っていた場合は、NGのLEDを点灯し、OKのLEDを消灯する。一度、NGのLEDを点灯したら、リセットするまで、そのまま保持する。
・WriteとReadの組みは0.2sec に1回行う。
Release 13.4 Map O.87xd (nt)
Xilinx Mapping Report File for Design 'system_top'
Design Information
------------------
Command Line : map -intstyle ise -p xc6slx45-csg324-2 -w -logic_opt off -ol
high -t 1 -xt 0 -register_duplication off -r 4 -global_opt off -mt off -ir off
-pr off -lc off -power off -o system_top_map.ncd system_top.ngd system_top.pcf
Target Device : xc6slx45
Target Package : csg324
Target Speed : -2
Mapper Version : spartan6 -- $Revision: 1.55 $
Mapped Date : MON 19 MAR 6:1:45 2012
Design Summary
--------------
Number of errors: 0
Number of warnings: 30
Slice Logic Utilization:
Number of Slice Registers: 4,171 out of 54,576 7%
Number used as Flip Flops: 4,156
Number used as Latches: 0
Number used as Latch-thrus: 0
Number used as AND/OR logics: 15
Number of Slice LUTs: 5,209 out of 27,288 19%
Number used as logic: 4,777 out of 27,288 17%
Number using O6 output only: 3,550
Number using O5 output only: 113
Number using O5 and O6: 1,114
Number used as ROM: 0
Number used as Memory: 292 out of 6,408 4%
Number used as Dual Port RAM: 108
Number using O6 output only: 4
Number using O5 output only: 1
Number using O5 and O6: 103
Number used as Single Port RAM: 4
Number using O6 output only: 4
Number using O5 output only: 0
Number using O5 and O6: 0
Number used as Shift Register: 180
Number using O6 output only: 83
Number using O5 output only: 1
Number using O5 and O6: 96
Number used exclusively as route-thrus: 140
Number with same-slice register load: 123
Number with same-slice carry load: 12
Number with other load: 5
Slice Logic Distribution:
Number of occupied Slices: 2,143 out of 6,822 31%
Nummber of MUXCYs used: 880 out of 13,644 6%
Number of LUT Flip Flop pairs used: 6,114
Number with an unused Flip Flop: 2,333 out of 6,114 38%
Number with an unused LUT: 905 out of 6,114 14%
Number of fully used LUT-FF pairs: 2,876 out of 6,114 47%
Number of unique control sets: 343
Number of slice register sites lost
to control set restrictions: 1,353 out of 54,576 2%
A LUT Flip Flop pair for this architecture represents one LUT paired with
one Flip Flop within a slice. A control set is a unique combination of
clock, reset, set, and enable signals for a registered element.
The Slice Logic Distribution report is not meaningful if the design is
over-mapped for a non-slice resource or if Placement fails.
IO Utilization:
Number of bonded IOBs: 97 out of 218 44%
Number of LOCed IOBs: 97 out of 97 100%
IOB Flip Flops: 11
IOB Master Pads: 4
IOB Slave Pads: 4
Specific Feature Utilization:
Number of RAMB16BWERs: 29 out of 116 25%
Number of RAMB8BWERs: 0 out of 232 0%
Number of BUFIO2/BUFIO2_2CLKs: 1 out of 32 3%
Number used as BUFIO2s: 1
Number used as BUFIO2_2CLKs: 0
Number of BUFIO2FB/BUFIO2FB_2CLKs: 0 out of 32 0%
Number of BUFG/BUFGMUXs: 5 out of 16 31%
Number used as BUFGs: 5
Number used as BUFGMUX: 0
Number of DCM/DCM_CLKGENs: 0 out of 8 0%
Number of ILOGIC2/ISERDES2s: 6 out of 376 1%
Number used as ILOGIC2s: 6
Number used as ISERDES2s: 0
Number of IODELAY2/IODRP2/IODRP2_MCBs: 24 out of 376 6%
Number used as IODELAY2s: 0
Number used as IODRP2s: 2
Number used as IODRP2_MCBs: 22
Number of OLOGIC2/OSERDES2s: 58 out of 376 15%
Number used as OLOGIC2s: 5
Number used as OSERDES2s: 53
Number of BSCANs: 1 out of 4 25%
Number of BUFHs: 0 out of 256 0%
Number of BUFPLLs: 1 out of 8 12%
Number of BUFPLL_MCBs: 1 out of 4 25%
Number of DSP48A1s: 3 out of 58 5%
Number of ICAPs: 0 out of 1 0%
Number of MCBs: 1 out of 2 50%
Number of PCILOGICSEs: 0 out of 2 0%
Number of PLL_ADVs: 2 out of 4 50%
Number of PMVs: 0 out of 1 0%
Number of STARTUPs: 0 out of 1 0%
Number of SUSPEND_SYNCs: 0 out of 1 0%
Average Fanout of Non-Clock Nets: 3.94
Peak Memory Usage: 407 MB
Total REAL time to MAP completion: 7 mins 6 secs
Total CPU time to MAP completion: 7 mins 20 secs
Program FPGA failed
Data2MEM failed.
PORT pixclk = "", DIR = I
PORT TMDS_tx_clk_p = "", DIR = O
PORT TMDS_tx_clk_n = "", DIR = O
PORT TMDS_tx_2_G_p = "", DIR = O
PORT TMDS_tx_2_G_n = "", DIR = O
PORT TMDS_tx_1_R_p = "", DIR = O
PORT TMDS_tx_1_R_n = "", DIR = O
PORT TMDS_tx_0_B_p = "", DIR = O
PORT TMDS_tx_0_B_n = "", DIR = O
lib CDC_axi_slave_v1_00_a CDC_axi_slave.vhd vhdl
lib CDC_axi_slave_v1_00_a dvi_disp.vhd vhdl
lib CDC_axi_slave_v1_00_a Digilent_RTL/Video.vhd vhdl
lib CDC_axi_slave_v1_00_a Digilent_RTL/DVITransmitter.vhd vhdl
lib CDC_axi_slave_v1_00_a Digilent_RTL/TMDSEncoder.vhd vhdl
lib CDC_axi_slave_v1_00_a Digilent_RTL/SerializerN_1.vhd vhdl
lib CDC_axi_slave_v1_00_a dvi_disp.vhd vhdl
lib CDC_axi_slave_v1_00_a CharDispCtrler.v verilog
lib CDC_axi_slave_v1_00_a char_gen_rom.v verilog
lib CDC_axi_slave_v1_00_a disp_timing.v verilog
lib CDC_axi_slave_v1_00_a frame_buffer.v verilog
// CDC_axi_slave_tb.v
`default_nettype none
`timescale 100ps / 1ps
module CDC_axi_slave_tb;
parameter DELAY = 10;
parameter NUMBER_OF_TEST = 100; // テストする数
// 間は省略
// test
// Write Channel
// wr_data生成、+1する
reg [15:0] wcount;
wire [31:0] wdata;
always @(posedge ACLK) begin
if (~ARESETN)
wcount <= 0;
else begin
if (S_AXI_WVALID & S_AXI_WREADY)
wcount <= wcount + 16'd1;
end
end
assign wdata = {{16{1'b0}}, wcount};
reg WriteTaskBusy = 1'b0;
integer wt_cnt;
initial begin
// Wait 100 ns for global reset to finish
#1000;
#5000; // 500nsec Wait, PLL Locked
@(posedge ACLK); // 次のクロックへ
#DELAY;
for (wt_cnt=0; wt_cnt<NUMBER_OF_TEST; wt_cnt=wt_cnt+1) begin
WriteTaskBusy = 1'b1;
MBFMi.AXI_Master_1Seq_Write(0, 32'h100, 8'd7, ASIZE_BT_4, ABURST_INCR, wdata, 0, 2);
MBFMi.AXI_Master_1Seq_Write(0, 32'h200, 8'd3, ASIZE_BT_4, ABURST_INCR, wdata, 1, 3);
MBFMi.AXI_Master_1Seq_Write(0, 32'h300, 8'd1, ASIZE_BT_4, ABURST_INCR, wdata, 1, 4);
MBFMi.AXI_Master_1Seq_Write(0, 32'h400, 8'd0, ASIZE_BT_4, ABURST_INCR, wdata, 1, 5);
WriteTaskBusy = 1'b0;
while (ReadTestBusy) begin // Read 終了待ち
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
end
// Read Channel
reg ReadTestBusy = 1'b0;
integer rd_cnt;
initial begin
// Wait 100 ns for global reset to finish
#1000;
#5000; // 500nsec Wait, PLL Locked
for (rd_cnt=0; rd_cnt<NUMBER_OF_TEST; rd_cnt=rd_cnt+1) begin
ReadTestBusy = 1'b1;
#1000;
@(posedge ACLK); // 次のクロックへ
#DELAY;
MBFMi.AXI_Master_1Seq_Read(0, 32'h100, 8'd7, ASIZE_BT_4, ABURST_INCR, 2);
MBFMi.AXI_Master_1Seq_Read(0, 32'h200, 8'd3, ASIZE_BT_4, ABURST_INCR, 3);
MBFMi.AXI_Master_1Seq_Read(0, 32'h300, 8'd1, ASIZE_BT_4, ABURST_INCR, 4);
MBFMi.AXI_Master_1Seq_Read(0, 32'h400, 8'd0, ASIZE_BT_4, ABURST_INCR, 5);
ReadTestBusy = 1'b0;
while (WriteTaskBusy) begin // Write の終了待ち
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
end
endmodule
// 下も省略
OVL_ERROR : OVL_INCREMENT : Error: Write data has not been incremented : Test expression is increased by a value other than specified : severity 1 : time 945000 : CDC_axi_slave_tb.OVLi.wr_data_check.ovl_error_t
OVL_ERROR : OVL_INCREMENT : Error: Read data has not been incremented : Test expression is increased by a value other than specified : severity 1 : time 1045000 : CDC_axi_slave_tb.OVLi.rd_data_check.ovl_error_t
OVL_ERROR : OVL_INCREMENT : Error: Write data has not been incremented : Test expression is increased by a value other than specified : severity 1 : time 1105000 : CDC_axi_slave_tb.OVLi.wr_data_check.ovl_error_t
OVL_ERROR : OVL_INCREMENT : Error: Write data has not been incremented : Test expression is increased by a value other than specified : severity 1 : time 1185000 : CDC_axi_slave_tb.OVLi.wr_data_check.ovl_error_t
// OVL_Checker.v
`default_nettype none
`timescale 100ps / 1ps
`include "std_ovl_defines.h"
module OVL_Checker (
input wire ACLK,
input wire ARESETN,
input wire [0:0] S_AXI_AWID,
input wire [31:0] S_AXI_AWADDR,
input wire [7:0] S_AXI_AWLEN,
input wire [2:0] S_AXI_AWSIZE,
input wire [1:0] S_AXI_AWBURST,
input wire [1:0] S_AXI_AWLOCK,
input wire [3:0] S_AXI_AWCACHE, // Normal Non-cacheable Non-bufferable
input wire [2:0] S_AXI_AWPROT,
input wire [3:0] S_AXI_AWREGION,
input wire [3:0] S_AXI_AWQOS,
input wire [0:0] S_AXI_AWUSER,
input wire S_AXI_AWVALID,
input wire [0:0] S_AXI_WID,
input wire [31:0] S_AXI_WDATA,
input wire [3:0] S_AXI_WSTRB,
input wire S_AXI_WLAST,
input wire [0:0] S_AXI_WUSER,
input wire S_AXI_WVALID,
input wire S_AXI_BREADY,
input wire [0:0] S_AXI_ARID,
input wire [31:0] S_AXI_ARADDR,
input wire [7:0] S_AXI_ARLEN,
input wire [2:0] S_AXI_ARSIZE,
input wire [1:0] S_AXI_ARBURST,
input wire [1:0] S_AXI_ARLOCK,
input wire [3:0] S_AXI_ARCACHE, // Normal Non-cacheable Non-bufferable
input wire [2:0] S_AXI_ARPROT,
input wire [3:0] S_AXI_ARREGION,
input wire [3:0] S_AXI_ARQOS,
input wire [0:0] S_AXI_ARUSER,
input wire S_AXI_ARVALID,
input wire S_AXI_RREADY,
input wire S_AXI_AWREADY,
input wire S_AXI_WREADY,
input wire [0:0] S_AXI_BID,
input wire [1:0] S_AXI_BRESP,
input wire [0:0] S_AXI_BUSER,
input wire S_AXI_BVALID,
input wire S_AXI_ARREADY,
input wire [0:0] S_AXI_RID,
input wire [31:0] S_AXI_RDATA,
input wire [1:0] S_AXI_RRESP,
input wire S_AXI_RLAST,
input wire [0:0] S_AXI_RUSER,
input wire S_AXI_RVALID
);
wire [`OVL_FIRE_WIDTH-1:0] fire_wr_data, fire_rd_data;
wire [`OVL_FIRE_WIDTH-1:0] fire_aw_hcheck, fire_ar_hcheck;
wire [`OVL_FIRE_WIDTH-1:0] fire_aw_never, fire_ar_never;
reg [7:0] countw, countr;
parameter idle_wts = 3'b001,
wr_data_tran = 3'b010,
wr_resp_tran = 3'b100;
reg [2:0] wr_tran_cs;
parameter idle_rts = 1'b0,
rd_data_tran = 1'b1;
reg rd_trans_cs;
// Wirte Transaction データが+1されていることをチェックする(BFM Check)
ovl_increment #(
`OVL_ERROR, // severity_level
32, // width
1, // value
`OVL_ASSERT, // property_type
"Error: Write data has not been incremented", // msg
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) wr_data_check (
ACLK, // clock
~ARESETN | (S_AXI_AWVALID & S_AXI_AWREADY), // reset, Write のアドレス転送でリセット
S_AXI_WVALID & S_AXI_WREADY, // enable
S_AXI_WDATA, // test_expr
fire_wr_data // fire parameter
);
// Read Transaction データが+1されていることをチェックする(BFM Check)
ovl_increment #(
`OVL_ERROR, // severity_level
32, // width
1, // value
`OVL_ASSERT, // property_type
"Error: Read data has not been incremented", // msg
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) rd_data_check (
ACLK, // clock
~ARESETN | (S_AXI_ARVALID & S_AXI_ARREADY), // reset, Read のアドレス転送でリセット
S_AXI_RVALID & S_AXI_RREADY, // enable
S_AXI_RDATA, // test_expr
fire_rd_data // fire parameter
);
// S_AXI_AWVALID とS_AXI_AWREADY のハンドシェークのテスト
ovl_handshake #(
`OVL_ERROR, // severity_level
1, // min_ack_cycle
32, // max_ack_cycle
1, // req_drop
1, // deassert_count
1, // max_ack_length
`OVL_ASSERT, // property_type
"Error: Handshake Error of S_AXI_AWREADY and S_AXI_AWVALID",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) aw_handshake_check (
ACLK, // clock
ARESETN, // reset
1'b1, // enable
S_AXI_AWVALID, // req
S_AXI_AWREADY, // ack
fire_aw_hcheck // fire parameter
);
// S_AXI_ARVALID とS_AXI_ARREADY のハンドシェークのテスト
ovl_handshake #(
`OVL_ERROR, // severity_level
1, // min_ack_cycle
32, // max_ack_cycle
1, // req_drop
1, // deassert_count
1, // max_ack_length
`OVL_ASSERT, // property_type
"Error: Handshake Error of S_AXI_ARREADY and S_AXI_ARVALID",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) ar_handshake_check (
ACLK, // clock
ARESETN, // reset
1'b1, // enable
S_AXI_ARVALID, // req
S_AXI_ARREADY, // ack
fire_ar_hcheck // fire parameter
);
// Write, S_AXI_AWREADY がアサートされるときは、S_AXI_WVALID, S_AXI_WREADY, S_AXI_WLAST, S_AXI_BVALID, S_AXI_BREADY はアサートされない。
ovl_never #(
`OVL_ERROR, // severity_level
`OVL_ASSERT, // property_type
"Write, Assert Error of S_AXI_AWREADY",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) aw_never_assert (
ACLK, // clock_edge
ARESETN, // reset
1'b1, // enable
S_AXI_AWREADY & (S_AXI_WVALID | S_AXI_WREADY | S_AXI_WLAST | S_AXI_BVALID | S_AXI_BREADY),
fire_aw_never
);
// Read, S_AXI_RREADY がアサートされるときは、 S_AXI_RVALID, S_AXI_RREADY, S_AXI_RLAST はアサートされない
ovl_never #(
`OVL_ERROR, // severity_level
`OVL_ASSERT, // property_type
"Read, Assert Error of S_AXI_RREADY",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) ar_never_assert (
ACLK, // clock_edge
ARESETN, // reset
1'b1, // enable
S_AXI_ARREADY & (S_AXI_RVALID | S_AXI_RREADY | S_AXI_RLAST),
fire_ar_never
);
// Write の転送数をカウントして、 S_AXI_WLAST の出力を確認するアサーション
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
countw <= 0;
else begin
if (S_AXI_AWVALID & S_AXI_AWREADY) begin // countw へロード
countw <= S_AXI_AWLEN;
end else if (S_AXI_WVALID & S_AXI_WREADY) begin // データ転送
if (countw==0) begin // データ転送終了
if (~S_AXI_WLAST) begin // countw==0 でS_AXI_WLASTが立たない
$display("%m: at time %t Error: countw==0 でS_AXI_WLASTが立たない",$time);
end
end
end
end
end
// Read の転送数をカウントして、 S_AXI_RLAST の出力を確認するアサーション
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
countr <= 0;
else begin
if (S_AXI_ARVALID & S_AXI_ARREADY) begin // countw へロード
countr <= S_AXI_ARLEN;
end else if (S_AXI_RVALID & S_AXI_RREADY) begin // データ転送
if (countr==0) begin // データ転送終了
if (~S_AXI_RLAST) begin // countw==0 でS_AXI_WLASTが立たない
$display("%m: at time %t Error: countr==0 でS_AXI_WLASTが立たない",$time);
end
end
end
end
end
// Write 動作用ステートマシン
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
wr_tran_cs <= idle_wts;
else begin
case (wr_tran_cs)
idle_wts :
if (S_AXI_AWREADY & (S_AXI_WVALID | S_AXI_WREADY | S_AXI_WLAST | S_AXI_BVALID | S_AXI_BREADY)) // エラー
$display("%m: at time %t S_AXI_AWREADY がアサートされた時に、その他のVALID, READY信号がアサートされた",$time);
else if (S_AXI_AWVALID & S_AXI_AWREADY) // アドレス転送終了
wr_tran_cs <= wr_data_tran;
wr_data_tran :
if (S_AXI_AWREADY | S_AXI_BVALID | S_AXI_BREADY) // エラー
$display("%m: at time %t Write データ転送中に、S_AXI_AWREADY | S_AXI_BVALID | S_AXI_BREADY がアサートされた",$time);
else if (S_AXI_WVALID & S_AXI_WREADY & S_AXI_WLAST) // データ転送終了
wr_tran_cs <= wr_resp_tran;
wr_resp_tran :
if (S_AXI_AWREADY | S_AXI_WVALID | S_AXI_WREADY | S_AXI_WLAST) // エラー
$display("%m: at time %t Write Response Channel 転送時に関連しない信号がアサートされた",$time);
else if (S_AXI_BVALID & S_AXI_BREADY) // Write Response Channel 転送終了
wr_tran_cs <= idle_wts;
endcase
end
end
// Read 動作用ステートマシン
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
rd_trans_cs <= idle_rts;
else begin
case (rd_trans_cs)
idle_rts :
if (S_AXI_ARREADY & (S_AXI_RVALID | S_AXI_RREADY | S_AXI_RLAST)) // エラー
$display("%m: at time %t S_AXI_ARREADY がアサートされた時に、その他のVALID, READY信号がアサートされた",$time);
else if (S_AXI_ARVALID & S_AXI_ARREADY) // アドレス転送終了
rd_trans_cs <= rd_data_tran;
rd_data_tran :
if (S_AXI_ARREADY) // エラー
$display("%m: at time %t Read データ転送中に、S_AXI_ARREADY がアサートされた",$time);
else if (S_AXI_RVALID & S_AXI_RREADY & S_AXI_RLAST) // データ転送終了
rd_trans_cs <= idle_rts;
endcase
end
end
endmodule
`default_nettype wire
// OVL Checker
OVL_Checker OVLi (
.ACLK(ACLK),
.ARESETN(ARESETN),
.S_AXI_AWID(S_AXI_AWID),
.S_AXI_AWADDR(S_AXI_AWADDR),
.S_AXI_AWLEN(S_AXI_AWLEN),
.S_AXI_AWSIZE(S_AXI_AWSIZE),
.S_AXI_AWBURST(S_AXI_AWBURST),
.S_AXI_AWLOCK(S_AXI_AWLOCK),
.S_AXI_AWCACHE(S_AXI_AWCACHE),
.S_AXI_AWPROT(S_AXI_AWPROT),
.S_AXI_AWREGION(S_AXI_AWREGION),
.S_AXI_AWQOS(S_AXI_AWQOS),
.S_AXI_AWUSER(S_AXI_AWUSER),
.S_AXI_AWVALID(S_AXI_AWVALID),
.S_AXI_AWREADY(S_AXI_AWREADY),
.S_AXI_WID(S_AXI_WID),
.S_AXI_WDATA(S_AXI_WDATA),
.S_AXI_WSTRB(S_AXI_WSTRB),
.S_AXI_WLAST(S_AXI_WLAST),
.S_AXI_WUSER(S_AXI_WUSER),
.S_AXI_WVALID(S_AXI_WVALID),
.S_AXI_WREADY(S_AXI_WREADY),
.S_AXI_BID(S_AXI_BID),
.S_AXI_BRESP(S_AXI_BRESP),
.S_AXI_BUSER(S_AXI_BUSER),
.S_AXI_BVALID(S_AXI_BVALID),
.S_AXI_BREADY(S_AXI_BREADY),
.S_AXI_ARID(S_AXI_ARID),
.S_AXI_ARADDR(S_AXI_ARADDR),
.S_AXI_ARLEN(S_AXI_ARLEN),
.S_AXI_ARSIZE(S_AXI_ARSIZE),
.S_AXI_ARBURST(S_AXI_ARBURST),
.S_AXI_ARLOCK(S_AXI_ARLOCK),
.S_AXI_ARCACHE(S_AXI_ARCACHE),
.S_AXI_ARPROT(S_AXI_ARPROT),
.S_AXI_ARREGION(S_AXI_ARREGION),
.S_AXI_ARQOS(S_AXI_ARQOS),
.S_AXI_ARUSER(S_AXI_ARUSER),
.S_AXI_ARVALID(S_AXI_ARVALID),
.S_AXI_ARREADY(S_AXI_ARREADY),
.S_AXI_RID(S_AXI_RID),
.S_AXI_RDATA(S_AXI_RDATA),
.S_AXI_RRESP(S_AXI_RRESP),
.S_AXI_RLAST(S_AXI_RLAST),
.S_AXI_RUSER(S_AXI_RUSER),
.S_AXI_RVALID(S_AXI_RVALID),
.S_AXI_RREADY(S_AXI_RREADY)
);
MBFMi.AXI_Master_1Seq_Write(0, 32'h100, 8'd4, ASIZE_BT_4, ABURST_INCR, 32'h12345678, 0, 2);
MBFMi.AXI_MASTER_WDC(32'h3333_4444, 4);
MBFMi.AXI_Master_1Seq_Read(0, 32'h100, 8'd4, ASIZE_BT_4, ABURST_INCR, 3);
// AXI4 bus Master Bus Fucntion Mode
`default_nettype none
`timescale 100ps / 1ps
module AXI4_Master_BFM #(
parameter DELAY = 10 )
(
input wire ACLK,
output reg [0:0] S_AXI_AWID = 0,
output reg [31:0] S_AXI_AWADDR = 0,
output reg [7:0] S_AXI_AWLEN = 0,
output reg [2:0] S_AXI_AWSIZE = 0,
output reg [1:0] S_AXI_AWBURST = 0,
output reg [1:0] S_AXI_AWLOCK = 0,
output reg [3:0] S_AXI_AWCACHE = 2, // Normal Non-cacheable Non-bufferable
output reg [2:0] S_AXI_AWPROT = 0,
output reg [3:0] S_AXI_AWREGION = 0,
output reg [3:0] S_AXI_AWQOS = 0,
output reg [0:0] S_AXI_AWUSER = 0,
output reg S_AXI_AWVALID = 0,
output reg [0:0] S_AXI_WID = 0,
output reg [31:0] S_AXI_WDATA = 0,
output reg [3:0] S_AXI_WSTRB = 0,
output reg S_AXI_WLAST = 0,
output reg [0:0] S_AXI_WUSER = 0,
output reg S_AXI_WVALID = 0,
output reg S_AXI_BREADY = 0,
output reg [0:0] S_AXI_ARID = 0,
output reg [31:0] S_AXI_ARADDR = 0,
output reg [7:0] S_AXI_ARLEN = 0,
output reg [2:0] S_AXI_ARSIZE = 0,
output reg [1:0] S_AXI_ARBURST = 0,
output reg [1:0] S_AXI_ARLOCK = 0,
output reg [3:0] S_AXI_ARCACHE = 2, // Normal Non-cacheable Non-bufferable
output reg [2:0] S_AXI_ARPROT = 0,
output reg [3:0] S_AXI_ARREGION = 0,
output reg [3:0] S_AXI_ARQOS = 0,
output reg [0:0] S_AXI_ARUSER = 0,
output reg S_AXI_ARVALID = 0,
output reg S_AXI_RREADY = 0,
input wire S_AXI_AWREADY,
input wire S_AXI_WREADY,
input wire [0:0] S_AXI_BID,
input wire [1:0] S_AXI_BRESP,
input wire [0:0] S_AXI_BUSER,
input wire S_AXI_BVALID,
input wire S_AXI_ARREADY,
input wire [0:0] S_AXI_RID,
input wire [31:0] S_AXI_RDATA,
input wire [1:0] S_AXI_RRESP,
input wire S_AXI_RLAST,
input wire [0:0] S_AXI_RUSER,
input wire S_AXI_RVALID
);
reg [7:0] awlen_hold = 0;
reg [0:0] wid_hold = 0;
reg axi_w_transaction_active = 0;
reg axi_r_transaction_active = 0;
reg [7:0] arlen_hold = 0;
// Write Channel
task AXI_Master_1Seq_Write; // Write Address, Write Data, Write Response をシーケンシャルにオーバーラップせずに行う。
input [0:0] awid;
input [31:0] awaddr;
input [7:0] awlen;
input [2:0] awsize;
input [1:0] awburst;
input [31:0] wdata;
input [7:0] wait_clk_bready;
input [7:0] wmax_wait;
begin
AXI_MASTER_WAC(awid, awaddr, awlen, awsize, awburst);
AXI_MASTER_WDC(wdata, wmax_wait);
AXI_MASTER_WRC(wait_clk_bready);
end
endtask
// Write Address Channel
task AXI_MASTER_WAC;
input [0:0] awid;
input [31:0] awaddr;
input [7:0] awlen;
input [2:0] awsize;
input [1:0] awburst;
begin
S_AXI_AWID = awid;
S_AXI_AWADDR = awaddr;
S_AXI_AWLEN = awlen;
S_AXI_AWSIZE = awsize;
S_AXI_AWBURST = awburst;
S_AXI_AWVALID = 1'b1;
if (axi_w_transaction_active == 1'b0) begin // AXI Write トランザクションが開始されている場合は戻る
awlen_hold = awlen; // Write Data Channel のためにバースト数を取っておく
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_AWREADY) begin // S_AXI_AWREADY が1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_AWID = 0;
S_AXI_AWADDR = 0;
S_AXI_AWLEN = 0;
S_AXI_AWSIZE = 0;
S_AXI_AWBURST = 0;
S_AXI_AWVALID = 1'b0;
@(posedge ACLK); // 次のクロックへ
#DELAY;
axi_w_transaction_active = 1'b1; // AXIトランザクション開始
end
end
endtask
// Write Data Channel
task AXI_MASTER_WDC; // WDATA は+1する
// とりあえず、WSTRBはオール1にする
input [31:0] wdata;
input [7:0] wmax_wait; // Write時の最大wait数
integer i, j, val;
begin
i = 0; j = 0;
S_AXI_WSTRB = 4'b1111;
while (i<=awlen_hold) begin
if (wmax_wait == 0) // wmax_wait が0の時は$random を実行しない
val = 0;
else
val = $unsigned($random) % (wmax_wait+1);
if (val == 0) // waitなし
S_AXI_WVALID = 1'b1;
else begin // waitあり
S_AXI_WVALID = 1'b0;
for (j=0; j<wmax_wait; j=j+1) begin
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
S_AXI_WVALID = 1'b1; // wait終了
end
if (i == awlen_hold)
S_AXI_WLAST = 1'b1;
else
S_AXI_WLAST = 1'b0;
S_AXI_WDATA = wdata;
wdata = wdata + 1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_WREADY) begin // S_AXI_WREADY が0の時は1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
i = i + 1;
end
S_AXI_WVALID = 1'b0;
S_AXI_WLAST = 1'b0;
S_AXI_WSTRB = 4'b0000;
end
endtask
// Write Response Channel
task AXI_MASTER_WRC; // wait_clk_bready
input [7:0] wait_clk_bready;
integer i;
begin
for (i=0; i<wait_clk_bready; i=i+1) begin
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
S_AXI_BREADY = 1'b1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_BVALID) begin // S_AXI_BVALID が1になるまでWait
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_BREADY = 1'b0;
axi_w_transaction_active = 1'b0; // AXIトランザクション終了
end
endtask
// Read Channel
task AXI_Master_1Seq_Read; // Read Address, Read Data をシーケンシャルに行う。
input [0:0] arid;
input [31:0] araddr;
input [7:0] arlen;
input [2:0] arsize;
input [1:0] arburst;
input [7:0] rmax_wait; // Read時の最大wait数
begin
AXI_MASTER_RAC(arid, araddr, arlen, arsize, arburst);
AXI_MASTER_RDC(rmax_wait);
end
endtask
// Read Address Channel
task AXI_MASTER_RAC;
input [0:0] arid;
input [31:0] araddr;
input [7:0] arlen;
input [2:0] arsize;
input [1:0] arburst;
begin
S_AXI_ARID = arid;
S_AXI_ARADDR = araddr;
S_AXI_ARLEN = arlen;
S_AXI_ARSIZE = arsize;
S_AXI_ARBURST = arburst;
S_AXI_ARVALID = 1'b1;
if (axi_r_transaction_active == 1'b0) begin // AXI Read トランザクションが開始されている場合は戻る
arlen_hold =arlen; // Read Data Channel のためにバースト数を取っておく
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_ARREADY) begin // S_AXI_ARREADY が1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_ARID = 0;
S_AXI_ARADDR = 0;
S_AXI_ARLEN = 0;
S_AXI_ARSIZE = 0;
S_AXI_ARBURST = 0;
S_AXI_ARVALID = 1'b0;
@(posedge ACLK); // 次のクロックへ
#DELAY;
axi_r_transaction_active = 1'b1; // AXIトランザクション開始
end
end
endtask
// Read Data Channel
task AXI_MASTER_RDC; // S_AXI_RLAST がアサートされるまでS_AXI_RREADY をアサートする
input [7:0] rmax_wait; // Read時の最大wait数
integer i, val;
begin
while (~(S_AXI_RLAST & S_AXI_RVALID & S_AXI_RREADY)) begin // S_AXI_RLAST & S_AXI_RVALID & S_AXI_RREADY で終了
if (rmax_wait == 0) begin // rmax_wait が0の時は$random を実行しない
val = 0;
S_AXI_RREADY = 1'b1;
end else begin
val = $unsigned($random) % (rmax_wait+1);
if (val == 0)
S_AXI_RREADY = 1'b1;
else
S_AXI_RREADY = 1'b0;
end
#DELAY;
for (i=0; i<val; i=i+1) begin // ランダム値でWait、val=0の時はスキップ
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
S_AXI_RREADY = 1'b1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_RVALID) begin // S_AXI_RVALID が1になるまでWait
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
end
#DELAY;
S_AXI_RREADY = 1'b0;
axi_r_transaction_active = 1'b0; // AXIトランザクション終了
end
endtask
endmodule
`default_nettype wire
// CDC_axi_slave_tb.v
`default_nettype none
`timescale 100ps / 1ps
module CDC_axi_slave_tb;
parameter DELAY = 10;
parameter ASIZE_BT_4 = 3'd2; // 32 bit width
parameter ASIZE_BT_2 = 3'd1; // 16 bit width
parameter ASIZE_BT_1 = 3'd0; // 8 bit width
parameter ABURST_FIXED = 2'd0;
parameter ABURST_INCR = 2'd1;
parameter ABURST_WRAP = 2'd2;
parameter BRESP_OKAY = 2'b00;
parameter BRESP_EXOKAY = 2'b01;
parameter BRESP_SLVERR = 2'b10;
parameter BRESP_DECERR = 2'b11;
// Inputs
wire ACLK;
wire ARESETN;
wire [0:0] S_AXI_AWID;
wire [31:0] S_AXI_AWADDR;
wire [7:0] S_AXI_AWLEN;
wire [2:0] S_AXI_AWSIZE;
wire [1:0] S_AXI_AWBURST;
wire [1:0] S_AXI_AWLOCK;
wire [3:0] S_AXI_AWCACHE;
wire [2:0] S_AXI_AWPROT;
wire [3:0] S_AXI_AWREGION;
wire [3:0] S_AXI_AWQOS;
wire [0:0] S_AXI_AWUSER;
wire S_AXI_AWVALID;
wire [0:0] S_AXI_WID;
wire [31:0] S_AXI_WDATA;
wire [3:0] S_AXI_WSTRB;
wire S_AXI_WLAST;
wire [0:0] S_AXI_WUSER;
wire S_AXI_WVALID;
wire S_AXI_BREADY;
wire [0:0] S_AXI_ARID;
wire [31:0] S_AXI_ARADDR;
wire [7:0] S_AXI_ARLEN;
wire [2:0] S_AXI_ARSIZE;
wire [1:0] S_AXI_ARBURST;
wire [1:0] S_AXI_ARLOCK;
wire [3:0] S_AXI_ARCACHE;
wire [2:0] S_AXI_ARPROT;
wire [3:0] S_AXI_ARREGION;
wire [3:0] S_AXI_ARQOS;
wire [0:0] S_AXI_ARUSER;
wire S_AXI_ARVALID;
wire S_AXI_RREADY;
wire pixclk;
// Outputs
reg S_AXI_AWREADY;
reg S_AXI_WREADY;
reg [0:0] S_AXI_BID;
reg [1:0] S_AXI_BRESP;
wire [0:0] S_AXI_BUSER = 0;
reg S_AXI_BVALID;
reg S_AXI_ARREADY;
reg [0:0] S_AXI_RID;
reg [31:0] S_AXI_RDATA;
reg [1:0] S_AXI_RRESP;
reg S_AXI_RLAST;
wire [0:0] S_AXI_RUSER = 0;
reg S_AXI_RVALID;
wire TMDS_tx_clk_p;
wire TMDS_tx_clk_n;
wire TMDS_tx_2_G_p;
wire TMDS_tx_2_G_n;
wire TMDS_tx_1_R_p;
wire TMDS_tx_1_R_n;
wire TMDS_tx_0_B_p;
wire TMDS_tx_0_B_n;
wire S_AXI_AWREADY_d;
wire S_AXI_WREADY_d;
wire [0:0] S_AXI_BID_d;
wire [1:0] S_AXI_BRESP_d;
wire S_AXI_BVALID_d;
wire S_AXI_ARREADY_d;
wire [0:0] S_AXI_RID_d;
wire [31:0] S_AXI_RDATA_d;
wire [1:0] S_AXI_RRESP_d;
wire S_AXI_RLAST_d;
wire S_AXI_RVALID_d;
// Instantiate the Unit Under Test (UUT)
CDC_axi_slave uut (
.ACLK(ACLK),
.ARESETN(ARESETN),
.S_AXI_AWID(S_AXI_AWID),
.S_AXI_AWADDR(S_AXI_AWADDR),
.S_AXI_AWLEN(S_AXI_AWLEN),
.S_AXI_AWSIZE(S_AXI_AWSIZE),
.S_AXI_AWBURST(S_AXI_AWBURST),
.S_AXI_AWLOCK(S_AXI_AWLOCK),
.S_AXI_AWCACHE(S_AXI_AWCACHE),
.S_AXI_AWPROT(S_AXI_AWPROT),
.S_AXI_AWREGION(S_AXI_AWREGION),
.S_AXI_AWQOS(S_AXI_AWQOS),
.S_AXI_AWUSER(S_AXI_AWUSER),
.S_AXI_AWVALID(S_AXI_AWVALID),
.S_AXI_AWREADY(S_AXI_AWREADY_d),
.S_AXI_WID(S_AXI_WID),
.S_AXI_WDATA(S_AXI_WDATA),
.S_AXI_WSTRB(S_AXI_WSTRB),
.S_AXI_WLAST(S_AXI_WLAST),
.S_AXI_WUSER(S_AXI_WUSER),
.S_AXI_WVALID(S_AXI_WVALID),
.S_AXI_WREADY(S_AXI_WREADY_d),
.S_AXI_BID(S_AXI_BID_d),
.S_AXI_BRESP(S_AXI_BRESP_d),
.S_AXI_BUSER(S_AXI_BUSER),
.S_AXI_BVALID(S_AXI_BVALID_d),
.S_AXI_BREADY(S_AXI_BREADY),
.S_AXI_ARID(S_AXI_ARID),
.S_AXI_ARADDR(S_AXI_ARADDR),
.S_AXI_ARLEN(S_AXI_ARLEN),
.S_AXI_ARSIZE(S_AXI_ARSIZE),
.S_AXI_ARBURST(S_AXI_ARBURST),
.S_AXI_ARLOCK(S_AXI_ARLOCK),
.S_AXI_ARCACHE(S_AXI_ARCACHE),
.S_AXI_ARPROT(S_AXI_ARPROT),
.S_AXI_ARREGION(S_AXI_ARREGION),
.S_AXI_ARQOS(S_AXI_ARQOS),
.S_AXI_ARUSER(S_AXI_ARUSER),
.S_AXI_ARVALID(S_AXI_ARVALID),
.S_AXI_ARREADY(S_AXI_ARREADY_d),
.S_AXI_RID(S_AXI_RID_d),
.S_AXI_RDATA(S_AXI_RDATA_d),
.S_AXI_RRESP(S_AXI_RRESP_d),
.S_AXI_RLAST(S_AXI_RLAST_d),
.S_AXI_RUSER(S_AXI_RUSER),
.S_AXI_RVALID(S_AXI_RVALID_d),
.S_AXI_RREADY(S_AXI_RREADY),
.pixclk(pixclk),
.TMDS_tx_clk_p(TMDS_tx_clk_p),
.TMDS_tx_clk_n(TMDS_tx_clk_n),
.TMDS_tx_2_G_p(TMDS_tx_2_G_p),
.TMDS_tx_2_G_n(TMDS_tx_2_G_n),
.TMDS_tx_1_R_p(TMDS_tx_1_R_p),
.TMDS_tx_1_R_n(TMDS_tx_1_R_n),
.TMDS_tx_0_B_p(TMDS_tx_0_B_p),
.TMDS_tx_0_B_n(TMDS_tx_0_B_n)
);
always @* S_AXI_AWREADY <= #DELAY S_AXI_AWREADY_d;
always @* S_AXI_WREADY <= #DELAY S_AXI_WREADY_d;
always @* S_AXI_BID <= #DELAY S_AXI_BID_d;
always @* S_AXI_BRESP <= #DELAY S_AXI_BRESP_d;
always @* S_AXI_BVALID <= #DELAY S_AXI_BVALID_d;
always @* S_AXI_ARREADY <= #DELAY S_AXI_ARREADY_d;
always @* S_AXI_RID <= #DELAY S_AXI_RID_d;
always @* S_AXI_RDATA <= #DELAY S_AXI_RDATA_d;
always @* S_AXI_RRESP <= #DELAY S_AXI_RRESP_d;
always @* S_AXI_RLAST <= #DELAY S_AXI_RLAST_d;
always @* S_AXI_RVALID <= #DELAY S_AXI_RVALID_d;
// clk_gen のインスタンス
clk_gen #(
.CLK_PERIOD(100), // 10nsec, 100MHz
.CLK_DUTY_CYCLE(0.5),
.CLK_OFFSET(0),
.START_STATE(1'b0)
) ACLKi (
.clk_out(ACLK)
);
clk_gen #(
.CLK_PERIOD(250), // 25nsec, 40MHz
.CLK_DUTY_CYCLE(0.5),
.CLK_OFFSET(0),
.START_STATE(1'b0)
) PIXCLKi (
.clk_out(pixclk)
);
// reset_gen のインスタンス
reset_gen #(
.RESET_STATE(1'b0),
.RESET_TIME(1000) // 100nsec
) RESETi (
.reset_out(ARESETN)
);
// AXI4_BFM のインスタンス
AXI4_Master_BFM #(.DELAY(DELAY)) MBFMi(
.ACLK(ACLK),
.S_AXI_AWID(S_AXI_AWID),
.S_AXI_AWADDR(S_AXI_AWADDR),
.S_AXI_AWLEN(S_AXI_AWLEN),
.S_AXI_AWSIZE(S_AXI_AWSIZE),
.S_AXI_AWBURST(S_AXI_AWBURST),
.S_AXI_AWLOCK(S_AXI_AWLOCK),
.S_AXI_AWCACHE(S_AXI_AWCACHE),
.S_AXI_AWPROT(S_AXI_AWPROT),
.S_AXI_AWREGION(S_AXI_AWREGION),
.S_AXI_AWQOS(S_AXI_AWQOS),
.S_AXI_AWUSER(S_AXI_AWUSER),
.S_AXI_AWVALID(S_AXI_AWVALID),
.S_AXI_AWREADY(S_AXI_AWREADY),
.S_AXI_WID(S_AXI_WID),
.S_AXI_WDATA(S_AXI_WDATA),
.S_AXI_WSTRB(S_AXI_WSTRB),
.S_AXI_WLAST(S_AXI_WLAST),
.S_AXI_WUSER(S_AXI_WUSER),
.S_AXI_WVALID(S_AXI_WVALID),
.S_AXI_WREADY(S_AXI_WREADY),
.S_AXI_BID(S_AXI_BID),
.S_AXI_BRESP(S_AXI_BRESP),
.S_AXI_BUSER(S_AXI_BUSER),
.S_AXI_BVALID(S_AXI_BVALID),
.S_AXI_BREADY(S_AXI_BREADY),
.S_AXI_ARID(S_AXI_ARID),
.S_AXI_ARADDR(S_AXI_ARADDR),
.S_AXI_ARLEN(S_AXI_ARLEN),
.S_AXI_ARSIZE(S_AXI_ARSIZE),
.S_AXI_ARBURST(S_AXI_ARBURST),
.S_AXI_ARLOCK(S_AXI_ARLOCK),
.S_AXI_ARCACHE(S_AXI_ARCACHE),
.S_AXI_ARPROT(S_AXI_ARPROT),
.S_AXI_ARREGION(S_AXI_ARREGION),
.S_AXI_ARQOS(S_AXI_ARQOS),
.S_AXI_ARUSER(S_AXI_ARUSER),
.S_AXI_ARVALID(S_AXI_ARVALID),
.S_AXI_ARREADY(S_AXI_ARREADY),
.S_AXI_RID(S_AXI_RID),
.S_AXI_RDATA(S_AXI_RDATA),
.S_AXI_RRESP(S_AXI_RRESP),
.S_AXI_RLAST(S_AXI_RLAST),
.S_AXI_RUSER(S_AXI_RUSER),
.S_AXI_RVALID(S_AXI_RVALID),
.S_AXI_RREADY(S_AXI_RREADY)
);
// test
// Write Channel
initial begin
// Wait 100 ns for global reset to finish
#1000;
#5000; // 500nsec Wait, PLL Locked
@(posedge ACLK); // 次のクロックへ
#DELAY;
MBFMi.AXI_Master_1Seq_Write(0, 32'h100, 8'd4, ASIZE_BT_4, ABURST_INCR, 32'h12345678, 0, 2);
MBFMi.AXI_Master_1Seq_Write(0, 32'h200, 8'd0, ASIZE_BT_4, ABURST_INCR, 32'h11223344, 1, 0);
// アドレス転送のオーバーラップのサンプル
// オーバーラップ後にもう一度、2度目のWrite Address Channel の転送を行う。
MBFMi.AXI_MASTER_WAC(0, 32'h300, 8'd0, ASIZE_BT_4, ABURST_INCR);
MBFMi.AXI_MASTER_WAC(0, 32'h400, 8'd0, ASIZE_BT_4, ABURST_INCR);
MBFMi.AXI_MASTER_WDC(32'h1111_2222, 2);
MBFMi.AXI_MASTER_WRC(0);
MBFMi.AXI_MASTER_WAC(0, 32'h400, 8'd0, ASIZE_BT_4, ABURST_INCR);
MBFMi.AXI_MASTER_WDC(32'h3333_4444, 4);
MBFMi.AXI_MASTER_WRC(0);
end
// Read Channel
initial begin
// Wait 100 ns for global reset to finish
#1000;
#5000; // 500nsec Wait, PLL Locked
@(posedge ACLK); // 次のクロックへ
#DELAY;
MBFMi.AXI_Master_1Seq_Read(0, 32'h100, 8'd4, ASIZE_BT_4, ABURST_INCR, 3);
MBFMi.AXI_Master_1Seq_Read(0, 32'h200, 8'd0, ASIZE_BT_4, ABURST_INCR, 4);
end
endmodule
module clk_gen #(
parameter CLK_PERIOD = 100,
parameter real CLK_DUTY_CYCLE = 0.5,
parameter CLK_OFFSET = 0,
parameter START_STATE = 1'b0 )
(
output reg clk_out
);
begin
initial begin
#CLK_OFFSET;
forever
begin
clk_out = START_STATE;
#(CLK_PERIOD-(CLK_PERIOD*CLK_DUTY_CYCLE)) clk_out = ~START_STATE;
#(CLK_PERIOD*CLK_DUTY_CYCLE);
end
end
end
endmodule
module reset_gen #(
parameter RESET_STATE = 1'b1,
parameter RESET_TIME = 100 )
(
output reg reset_out
);
begin
initial begin
reset_out = RESET_STATE;
#RESET_TIME;
reset_out = ~RESET_STATE;
end
end
endmodule
`default_nettype wire
// AXI4 bus Master Bus Fucntion Mode
`default_nettype none
`timescale 100ps / 1ps
module AXI4_Master_BFM #(
parameter DELAY = 10 )
(
input wire ACLK,
output reg [0:0] S_AXI_AWID = 0,
output reg [31:0] S_AXI_AWADDR = 0,
output reg [7:0] S_AXI_AWLEN = 0,
output reg [2:0] S_AXI_AWSIZE = 0,
output reg [1:0] S_AXI_AWBURST = 0,
output reg [1:0] S_AXI_AWLOCK = 0,
output reg [3:0] S_AXI_AWCACHE = 2, // Normal Non-cacheable Non-bufferable
output reg [2:0] S_AXI_AWPROT = 0,
output reg [3:0] S_AXI_AWREGION = 0,
output reg [3:0] S_AXI_AWQOS = 0,
output reg [0:0] S_AXI_AWUSER = 0,
output reg S_AXI_AWVALID = 0,
output reg [0:0] S_AXI_WID = 0,
output reg [31:0] S_AXI_WDATA = 0,
output reg [3:0] S_AXI_WSTRB = 0,
output reg S_AXI_WLAST = 0,
output reg [0:0] S_AXI_WUSER = 0,
output reg S_AXI_WVALID = 0,
output reg S_AXI_BREADY = 0,
output reg [0:0] S_AXI_ARID = 0,
output reg [31:0] S_AXI_ARADDR = 0,
output reg [7:0] S_AXI_ARLEN = 0,
output reg [2:0] S_AXI_ARSIZE = 0,
output reg [1:0] S_AXI_ARBURST = 0,
output reg [1:0] S_AXI_ARLOCK = 0,
output reg [3:0] S_AXI_ARCACHE = 2, // Normal Non-cacheable Non-bufferable
output reg [2:0] S_AXI_ARPROT = 0,
output reg [3:0] S_AXI_ARREGION = 0,
output reg [3:0] S_AXI_ARQOS = 0,
output reg [0:0] S_AXI_ARUSER = 0,
output reg S_AXI_ARVALID = 0,
output reg S_AXI_RREADY = 0,
input wire S_AXI_AWREADY,
input wire S_AXI_WREADY,
input wire [0:0] S_AXI_BID,
input wire [1:0] S_AXI_BRESP,
input wire [0:0] S_AXI_BUSER,
input wire S_AXI_BVALID,
input wire S_AXI_ARREADY,
input wire [0:0] S_AXI_RID,
input wire [31:0] S_AXI_RDATA,
input wire [1:0] S_AXI_RRESP,
input wire S_AXI_RLAST,
input wire [0:0] S_AXI_RUSER,
input wire S_AXI_RVALID
);
reg [7:0] awlen_hold = 0;
reg [0:0] wid_hold = 0;
reg axi_w_transaction_active = 0;
reg axi_r_transaction_active = 0;
reg [7:0] arlen_hold = 0;
// Write Channel
task AXI_Master_1Seq_Write; // Write Address, Write Data, Write Response をシーケンシャルにオーバーラップせずに行う。
input [0:0] awid;
input [31:0] awaddr;
input [7:0] awlen;
input [2:0] awsize;
input [1:0] awburst;
input [31:0] wdata;
input [7:0] wait_clk_bready;
begin
AXI_MASTER_WAC(awid, awaddr, awlen, awsize, awburst);
AXI_MASTER_WDC(wdata);
AXI_MASTER_WRC(wait_clk_bready);
end
endtask
// Write Address Channel
task AXI_MASTER_WAC;
input [0:0] awid;
input [31:0] awaddr;
input [7:0] awlen;
input [2:0] awsize;
input [1:0] awburst;
begin
S_AXI_AWID = awid;
S_AXI_AWADDR = awaddr;
S_AXI_AWLEN = awlen;
S_AXI_AWSIZE = awsize;
S_AXI_AWBURST = awburst;
S_AXI_AWVALID = 1'b1;
if (axi_w_transaction_active == 1'b0) begin // AXI Write トランザクションが開始されている場合は戻る
awlen_hold = awlen; // Write Data Channel のためにバースト数を取っておく
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_AWREADY) begin // S_AXI_AWREADY が1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_AWID = 0;
S_AXI_AWADDR = 0;
S_AXI_AWLEN = 0;
S_AXI_AWSIZE = 0;
S_AXI_AWBURST = 0;
S_AXI_AWVALID = 1'b0;
@(posedge ACLK); // 次のクロックへ
#DELAY;
axi_w_transaction_active = 1'b1; // AXIトランザクション開始
end
end
endtask
// Write Data Channel
task AXI_MASTER_WDC; // WDATA は+1する
// とりあえず、WSTRBはオール1にする
input [31:0] wdata;
integer i;
begin
i = 0;
while (i<=awlen_hold) begin
S_AXI_WVALID = 1'b1;
S_AXI_WSTRB = 4'b1111;
if (i == awlen_hold)
S_AXI_WLAST = 1'b1;
else
S_AXI_WLAST = 1'b0;
S_AXI_WDATA = wdata;
wdata = wdata + 1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_WREADY) begin // S_AXI_WREADY が0の時は1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
i = i + 1;
end
S_AXI_WVALID = 1'b0;
S_AXI_WLAST = 1'b0;
S_AXI_WSTRB = 4'b0000;
end
endtask
// Write Response Channel
task AXI_MASTER_WRC; // wait_clk_bready
input [7:0] wait_clk_bready;
integer i;
begin
for (i=0; i<wait_clk_bready; i=i+1) begin
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
S_AXI_BREADY = 1'b1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_BVALID) begin // S_AXI_BVALID が1になるまでWait
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_BREADY = 1'b0;
axi_w_transaction_active = 1'b0; // AXIトランザクション終了
end
endtask
// Read Channel
task AXI_Master_1Seq_Read; // Read Address, Read Data をシーケンシャルに行う。
input [0:0] arid;
input [31:0] araddr;
input [7:0] arlen;
input [2:0] arsize;
input [1:0] arburst;
begin
AXI_MASTER_RAC(arid, araddr, arlen, arsize, arburst);
AXI_MASTER_RDC();
end
endtask
// Read Address Channel
task AXI_MASTER_RAC;
input [0:0] arid;
input [31:0] araddr;
input [7:0] arlen;
input [2:0] arsize;
input [1:0] arburst;
begin
S_AXI_ARID = arid;
S_AXI_ARADDR = araddr;
S_AXI_ARLEN = arlen;
S_AXI_ARSIZE = arsize;
S_AXI_ARBURST = arburst;
S_AXI_ARVALID = 1'b1;
if (axi_r_transaction_active == 1'b0) begin // AXI Read トランザクションが開始されている場合は戻る
arlen_hold =arlen; // Read Data Channel のためにバースト数を取っておく
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_ARREADY) begin // S_AXI_ARREADY が1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_ARID = 0;
S_AXI_ARADDR = 0;
S_AXI_ARLEN = 0;
S_AXI_ARSIZE = 0;
S_AXI_ARBURST = 0;
S_AXI_ARVALID = 1'b0;
@(posedge ACLK); // 次のクロックへ
#DELAY;
axi_r_transaction_active = 1'b1; // AXIトランザクション開始
end
end
endtask
// Read Data Channel
task AXI_MASTER_RDC; // S_AXI_RLAST がアサートされるまでS_AXI_RREADY をアサートする
begin
S_AXI_RREADY = 1'b1;
@(posedge ACLK); // 次のクロックへ
while (~(S_AXI_RLAST & S_AXI_RVALID)) begin // S_AXI_RLAST & S_AXI_RVALID までS_AXI_RREADY を1にアサートする
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_RREADY = 1'b0;
axi_r_transaction_active = 1'b0; // AXIトランザクション終了
end
endtask
endmodule
`default_nettype wire
// CDC_axi_slave_tb.v
`default_nettype none
`timescale 100ps / 1ps
module CDC_axi_slave_tb;
parameter DELAY = 10;
parameter ASIZE_BT_4 = 3'd2; // 32 bit width
parameter ASIZE_BT_2 = 3'd1; // 16 bit width
parameter ASIZE_BT_1 = 3'd0; // 8 bit width
parameter ABURST_FIXED = 2'd0;
parameter ABURST_INCR = 2'd1;
parameter ABURST_WRAP = 2'd2;
parameter BRESP_OKAY = 2'b00;
parameter BRESP_EXOKAY = 2'b01;
parameter BRESP_SLVERR = 2'b10;
parameter BRESP_DECERR = 2'b11;
// Inputs
wire ACLK;
wire ARESETN;
wire [0:0] S_AXI_AWID;
wire [31:0] S_AXI_AWADDR;
wire [7:0] S_AXI_AWLEN;
wire [2:0] S_AXI_AWSIZE;
wire [1:0] S_AXI_AWBURST;
wire [1:0] S_AXI_AWLOCK;
wire [3:0] S_AXI_AWCACHE;
wire [2:0] S_AXI_AWPROT;
wire [3:0] S_AXI_AWREGION;
wire [3:0] S_AXI_AWQOS;
wire [0:0] S_AXI_AWUSER;
wire S_AXI_AWVALID;
wire [0:0] S_AXI_WID;
wire [31:0] S_AXI_WDATA;
wire [3:0] S_AXI_WSTRB;
wire S_AXI_WLAST;
wire [0:0] S_AXI_WUSER;
wire S_AXI_WVALID;
wire S_AXI_BREADY;
wire [0:0] S_AXI_ARID;
wire [31:0] S_AXI_ARADDR;
wire [7:0] S_AXI_ARLEN;
wire [2:0] S_AXI_ARSIZE;
wire [1:0] S_AXI_ARBURST;
wire [1:0] S_AXI_ARLOCK;
wire [3:0] S_AXI_ARCACHE;
wire [2:0] S_AXI_ARPROT;
wire [3:0] S_AXI_ARREGION;
wire [3:0] S_AXI_ARQOS;
wire [0:0] S_AXI_ARUSER;
wire S_AXI_ARVALID;
wire S_AXI_RREADY;
wire pixclk;
// Outputs
reg S_AXI_AWREADY;
reg S_AXI_WREADY;
reg [0:0] S_AXI_BID;
reg [1:0] S_AXI_BRESP;
wire [0:0] S_AXI_BUSER = 0;
reg S_AXI_BVALID;
reg S_AXI_ARREADY;
reg [0:0] S_AXI_RID;
reg [31:0] S_AXI_RDATA;
reg [1:0] S_AXI_RRESP;
reg S_AXI_RLAST;
wire [0:0] S_AXI_RUSER = 0;
reg S_AXI_RVALID;
wire TMDS_tx_clk_p;
wire TMDS_tx_clk_n;
wire TMDS_tx_2_G_p;
wire TMDS_tx_2_G_n;
wire TMDS_tx_1_R_p;
wire TMDS_tx_1_R_n;
wire TMDS_tx_0_B_p;
wire TMDS_tx_0_B_n;
wire S_AXI_AWREADY_d;
wire S_AXI_WREADY_d;
wire [0:0] S_AXI_BID_d;
wire [1:0] S_AXI_BRESP_d;
wire S_AXI_BVALID_d;
wire S_AXI_ARREADY_d;
wire [0:0] S_AXI_RID_d;
wire [31:0] S_AXI_RDATA_d;
wire [1:0] S_AXI_RRESP_d;
wire S_AXI_RLAST_d;
wire S_AXI_RVALID_d;
// Instantiate the Unit Under Test (UUT)
CDC_axi_slave uut (
.ACLK(ACLK),
.ARESETN(ARESETN),
.S_AXI_AWID(S_AXI_AWID),
.S_AXI_AWADDR(S_AXI_AWADDR),
.S_AXI_AWLEN(S_AXI_AWLEN),
.S_AXI_AWSIZE(S_AXI_AWSIZE),
.S_AXI_AWBURST(S_AXI_AWBURST),
.S_AXI_AWLOCK(S_AXI_AWLOCK),
.S_AXI_AWCACHE(S_AXI_AWCACHE),
.S_AXI_AWPROT(S_AXI_AWPROT),
.S_AXI_AWREGION(S_AXI_AWREGION),
.S_AXI_AWQOS(S_AXI_AWQOS),
.S_AXI_AWUSER(S_AXI_AWUSER),
.S_AXI_AWVALID(S_AXI_AWVALID),
.S_AXI_AWREADY(S_AXI_AWREADY_d),
.S_AXI_WID(S_AXI_WID),
.S_AXI_WDATA(S_AXI_WDATA),
.S_AXI_WSTRB(S_AXI_WSTRB),
.S_AXI_WLAST(S_AXI_WLAST),
.S_AXI_WUSER(S_AXI_WUSER),
.S_AXI_WVALID(S_AXI_WVALID),
.S_AXI_WREADY(S_AXI_WREADY_d),
.S_AXI_BID(S_AXI_BID_d),
.S_AXI_BRESP(S_AXI_BRESP_d),
.S_AXI_BUSER(S_AXI_BUSER),
.S_AXI_BVALID(S_AXI_BVALID_d),
.S_AXI_BREADY(S_AXI_BREADY),
.S_AXI_ARID(S_AXI_ARID),
.S_AXI_ARADDR(S_AXI_ARADDR),
.S_AXI_ARLEN(S_AXI_ARLEN),
.S_AXI_ARSIZE(S_AXI_ARSIZE),
.S_AXI_ARBURST(S_AXI_ARBURST),
.S_AXI_ARLOCK(S_AXI_ARLOCK),
.S_AXI_ARCACHE(S_AXI_ARCACHE),
.S_AXI_ARPROT(S_AXI_ARPROT),
.S_AXI_ARREGION(S_AXI_ARREGION),
.S_AXI_ARQOS(S_AXI_ARQOS),
.S_AXI_ARUSER(S_AXI_ARUSER),
.S_AXI_ARVALID(S_AXI_ARVALID),
.S_AXI_ARREADY(S_AXI_ARREADY_d),
.S_AXI_RID(S_AXI_RID_d),
.S_AXI_RDATA(S_AXI_RDATA_d),
.S_AXI_RRESP(S_AXI_RRESP_d),
.S_AXI_RLAST(S_AXI_RLAST_d),
.S_AXI_RUSER(S_AXI_RUSER),
.S_AXI_RVALID(S_AXI_RVALID_d),
.S_AXI_RREADY(S_AXI_RREADY),
.pixclk(pixclk),
.TMDS_tx_clk_p(TMDS_tx_clk_p),
.TMDS_tx_clk_n(TMDS_tx_clk_n),
.TMDS_tx_2_G_p(TMDS_tx_2_G_p),
.TMDS_tx_2_G_n(TMDS_tx_2_G_n),
.TMDS_tx_1_R_p(TMDS_tx_1_R_p),
.TMDS_tx_1_R_n(TMDS_tx_1_R_n),
.TMDS_tx_0_B_p(TMDS_tx_0_B_p),
.TMDS_tx_0_B_n(TMDS_tx_0_B_n)
);
always @* S_AXI_AWREADY <= #DELAY S_AXI_AWREADY_d;
always @* S_AXI_WREADY <= #DELAY S_AXI_WREADY_d;
always @* S_AXI_BID <= #DELAY S_AXI_BID_d;
always @* S_AXI_BRESP <= #DELAY S_AXI_BRESP_d;
always @* S_AXI_BVALID <= #DELAY S_AXI_BVALID_d;
always @* S_AXI_ARREADY <= #DELAY S_AXI_ARREADY_d;
always @* S_AXI_RID <= #DELAY S_AXI_RID_d;
always @* S_AXI_RDATA <= #DELAY S_AXI_RDATA_d;
always @* S_AXI_RRESP <= #DELAY S_AXI_RRESP_d;
always @* S_AXI_RLAST <= #DELAY S_AXI_RLAST_d;
always @* S_AXI_RVALID <= #DELAY S_AXI_RVALID_d;
// clk_gen のインスタンス
clk_gen #(
.CLK_PERIOD(100), // 10nsec, 100MHz
.CLK_DUTY_CYCLE(0.5),
.CLK_OFFSET(0),
.START_STATE(1'b0)
) ACLKi (
.clk_out(ACLK)
);
clk_gen #(
.CLK_PERIOD(250), // 25nsec, 40MHz
.CLK_DUTY_CYCLE(0.5),
.CLK_OFFSET(0),
.START_STATE(1'b0)
) PIXCLKi (
.clk_out(pixclk)
);
// reset_gen のインスタンス
reset_gen #(
.RESET_STATE(1'b0),
.RESET_TIME(1000) // 100nsec
) RESETi (
.reset_out(ARESETN)
);
// AXI4_BFM のインスタンス
AXI4_Master_BFM #(.DELAY(DELAY)) MBFMi(
.ACLK(ACLK),
.S_AXI_AWID(S_AXI_AWID),
.S_AXI_AWADDR(S_AXI_AWADDR),
.S_AXI_AWLEN(S_AXI_AWLEN),
.S_AXI_AWSIZE(S_AXI_AWSIZE),
.S_AXI_AWBURST(S_AXI_AWBURST),
.S_AXI_AWLOCK(S_AXI_AWLOCK),
.S_AXI_AWCACHE(S_AXI_AWCACHE),
.S_AXI_AWPROT(S_AXI_AWPROT),
.S_AXI_AWREGION(S_AXI_AWREGION),
.S_AXI_AWQOS(S_AXI_AWQOS),
.S_AXI_AWUSER(S_AXI_AWUSER),
.S_AXI_AWVALID(S_AXI_AWVALID),
.S_AXI_AWREADY(S_AXI_AWREADY),
.S_AXI_WID(S_AXI_WID),
.S_AXI_WDATA(S_AXI_WDATA),
.S_AXI_WSTRB(S_AXI_WSTRB),
.S_AXI_WLAST(S_AXI_WLAST),
.S_AXI_WUSER(S_AXI_WUSER),
.S_AXI_WVALID(S_AXI_WVALID),
.S_AXI_WREADY(S_AXI_WREADY),
.S_AXI_BID(S_AXI_BID),
.S_AXI_BRESP(S_AXI_BRESP),
.S_AXI_BUSER(S_AXI_BUSER),
.S_AXI_BVALID(S_AXI_BVALID),
.S_AXI_BREADY(S_AXI_BREADY),
.S_AXI_ARID(S_AXI_ARID),
.S_AXI_ARADDR(S_AXI_ARADDR),
.S_AXI_ARLEN(S_AXI_ARLEN),
.S_AXI_ARSIZE(S_AXI_ARSIZE),
.S_AXI_ARBURST(S_AXI_ARBURST),
.S_AXI_ARLOCK(S_AXI_ARLOCK),
.S_AXI_ARCACHE(S_AXI_ARCACHE),
.S_AXI_ARPROT(S_AXI_ARPROT),
.S_AXI_ARREGION(S_AXI_ARREGION),
.S_AXI_ARQOS(S_AXI_ARQOS),
.S_AXI_ARUSER(S_AXI_ARUSER),
.S_AXI_ARVALID(S_AXI_ARVALID),
.S_AXI_ARREADY(S_AXI_ARREADY),
.S_AXI_RID(S_AXI_RID),
.S_AXI_RDATA(S_AXI_RDATA),
.S_AXI_RRESP(S_AXI_RRESP),
.S_AXI_RLAST(S_AXI_RLAST),
.S_AXI_RUSER(S_AXI_RUSER),
.S_AXI_RVALID(S_AXI_RVALID),
.S_AXI_RREADY(S_AXI_RREADY)
);
// test
// Write Channel
initial begin
// Wait 100 ns for global reset to finish
#1000;
#5000; // 500nsec Wait, PLL Locked
@(posedge ACLK); // 次のクロックへ
#DELAY;
MBFMi.AXI_Master_1Seq_Write(0, 32'h100, 8'd4, ASIZE_BT_4, ABURST_INCR, 32'h12345678, 0);
MBFMi.AXI_Master_1Seq_Write(0, 32'h200, 8'd0, ASIZE_BT_4, ABURST_INCR, 32'h11223344, 1);
// アドレス転送のオーバーラップのサンプル
// オーバーラップ後にもう一度、2度目のWrite Address Channel の転送を行う。
MBFMi.AXI_MASTER_WAC(0, 32'h300, 8'd0, ASIZE_BT_4, ABURST_INCR);
MBFMi.AXI_MASTER_WAC(0, 32'h400, 8'd0, ASIZE_BT_4, ABURST_INCR);
MBFMi.AXI_MASTER_WDC(32'h1111_2222);
MBFMi.AXI_MASTER_WRC(0);
MBFMi.AXI_MASTER_WAC(0, 32'h400, 8'd0, ASIZE_BT_4, ABURST_INCR);
MBFMi.AXI_MASTER_WDC(32'h3333_4444);
MBFMi.AXI_MASTER_WRC(0);
end
// Read Channel
initial begin
// Wait 100 ns for global reset to finish
#1000;
#5000; // 500nsec Wait, PLL Locked
@(posedge ACLK); // 次のクロックへ
#DELAY;
MBFMi.AXI_Master_1Seq_Read(0, 32'h100, 8'd4, ASIZE_BT_4, ABURST_INCR);
MBFMi.AXI_Master_1Seq_Read(0, 32'h200, 8'd0, ASIZE_BT_4, ABURST_INCR);
end
endmodule
module clk_gen #(
parameter CLK_PERIOD = 100,
parameter real CLK_DUTY_CYCLE = 0.5,
parameter CLK_OFFSET = 0,
parameter START_STATE = 1'b0 )
(
output reg clk_out
);
begin
initial begin
#CLK_OFFSET;
forever
begin
clk_out = START_STATE;
#(CLK_PERIOD-(CLK_PERIOD*CLK_DUTY_CYCLE)) clk_out = ~START_STATE;
#(CLK_PERIOD*CLK_DUTY_CYCLE);
end
end
end
endmodule
module reset_gen #(
parameter RESET_STATE = 1'b1,
parameter RESET_TIME = 100 )
(
output reg reset_out
);
begin
initial begin
reset_out = RESET_STATE;
#RESET_TIME;
reset_out = ~RESET_STATE;
end
end
endmodule
`default_nettype wire
1.0x100番地から、12345678の値をWriteし、+1しながら5バーストWrite
2.0x200番地に、11223344の値をWrite
3.オーバーラップのサンプル、0x300番地に11112222の値をWrite
4.オーバーラップのサンプル、0x400番地に33334444の値をWrite
1.0x100番地から、00005678の値を読み出せた。その後+1しながらReadバーストし、最後の値は0000567Cだった。
2.0x200番地から00003344の値を読み出せた。
`default_nettype none
`timescale 100ps / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 03:54:02 02/29/2012
// Design Name: CDC_axi_slave
// Module Name: H:/HDL/FndtnISEWork/Spartan6/Atlys/Atlys_XPS_CDC_SVGA_134/pcores/CDC_axi_slave_v1_00_a/CDC_axi_slave/CDC_axi_slave_tb.v
// Project Name: afifo_sm
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: CDC_axi_slave
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////
module CDC_axi_slave_tb;
parameter DELAY = 10;
parameter ASIZE_BT_4 = 3'd2; // 32 bit width
parameter ASIZE_BT_2 = 3'd1; // 16 bit width
parameter ASIZE_BT_1 = 3'd0; // 8 bit width
parameter ABURST_FIXED = 2'd0;
parameter ABURST_INCR = 2'd1;
parameter ABURST_WRAP = 2'd2;
parameter BRESP_OKAY = 2'b00;
parameter BRESP_EXOKAY = 2'b01;
parameter BRESP_SLVERR = 2'b10;
parameter BRESP_DECERR = 2'b11;
// Inputs
reg ACLK;
reg ARESETN;
reg [0:0] S_AXI_AWID;
reg [31:0] S_AXI_AWADDR;
reg [7:0] S_AXI_AWLEN;
reg [2:0] S_AXI_AWSIZE;
reg [1:0] S_AXI_AWBURST;
reg [1:0] S_AXI_AWLOCK;
reg [3:0] S_AXI_AWCACHE;
reg [2:0] S_AXI_AWPROT;
reg [3:0] S_AXI_AWREGION;
reg [3:0] S_AXI_AWQOS;
reg [0:0] S_AXI_AWUSER;
reg S_AXI_AWVALID;
reg [0:0] S_AXI_WID;
reg [31:0] S_AXI_WDATA;
reg [3:0] S_AXI_WSTRB;
reg S_AXI_WLAST;
reg [0:0] S_AXI_WUSER;
reg S_AXI_WVALID;
reg S_AXI_BREADY;
reg [0:0] S_AXI_ARID;
reg [31:0] S_AXI_ARADDR;
reg [7:0] S_AXI_ARLEN;
reg [2:0] S_AXI_ARSIZE;
reg [1:0] S_AXI_ARBURST;
reg [1:0] S_AXI_ARLOCK;
reg [3:0] S_AXI_ARCACHE;
reg [2:0] S_AXI_ARPROT;
reg [3:0] S_AXI_ARREGION;
reg [3:0] S_AXI_ARQOS;
reg [0:0] S_AXI_ARUSER;
reg S_AXI_ARVALID;
reg S_AXI_RREADY;
reg pixclk;
// Outputs
wire S_AXI_AWREADY;
wire S_AXI_WREADY;
wire [0:0] S_AXI_BID;
wire [1:0] S_AXI_BRESP;
wire [0:0] S_AXI_BUSER;
wire S_AXI_BVALID;
wire S_AXI_ARREADY;
wire [0:0] S_AXI_RID;
wire [31:0] S_AXI_RDATA;
wire [1:0] S_AXI_RRESP;
wire S_AXI_RLAST;
wire [0:0] S_AXI_RUSER;
wire S_AXI_RVALID;
wire TMDS_tx_clk_p;
wire TMDS_tx_clk_n;
wire TMDS_tx_2_G_p;
wire TMDS_tx_2_G_n;
wire TMDS_tx_1_R_p;
wire TMDS_tx_1_R_n;
wire TMDS_tx_0_B_p;
wire TMDS_tx_0_B_n;
wire S_AXI_AWREADY_d;
wire S_AXI_WREADY_d;
wire [0:0] S_AXI_BID_d;
wire [1:0] S_AXI_BRESP_d;
wire S_AXI_BVALID_d;
wire S_AXI_ARREADY_d;
wire [0:0] S_AXI_RID_d;
wire [31:0] S_AXI_RDATA_d;
wire [1:0] S_AXI_RRESP_d;
wire S_AXI_RLAST_d;
wire S_AXI_RVALID_d;
reg [7:0] awlen_hold = 0;
reg axi_w_transaction_active = 0;
reg axi_r_transaction_active = 0;
reg [7:0] arlen_hold = 0;
// Instantiate the Unit Under Test (UUT)
CDC_axi_slave uut (
.ACLK(ACLK),
.ARESETN(ARESETN),
.S_AXI_AWID(S_AXI_AWID),
.S_AXI_AWADDR(S_AXI_AWADDR),
.S_AXI_AWLEN(S_AXI_AWLEN),
.S_AXI_AWSIZE(S_AXI_AWSIZE),
.S_AXI_AWBURST(S_AXI_AWBURST),
.S_AXI_AWLOCK(S_AXI_AWLOCK),
.S_AXI_AWCACHE(S_AXI_AWCACHE),
.S_AXI_AWPROT(S_AXI_AWPROT),
.S_AXI_AWREGION(S_AXI_AWREGION),
.S_AXI_AWQOS(S_AXI_AWQOS),
.S_AXI_AWUSER(S_AXI_AWUSER),
.S_AXI_AWVALID(S_AXI_AWVALID),
.S_AXI_AWREADY(S_AXI_AWREADY_d),
.S_AXI_WID(S_AXI_WID),
.S_AXI_WDATA(S_AXI_WDATA),
.S_AXI_WSTRB(S_AXI_WSTRB),
.S_AXI_WLAST(S_AXI_WLAST),
.S_AXI_WUSER(S_AXI_WUSER),
.S_AXI_WVALID(S_AXI_WVALID),
.S_AXI_WREADY(S_AXI_WREADY_d),
.S_AXI_BID(S_AXI_BID_d),
.S_AXI_BRESP(S_AXI_BRESP_d),
.S_AXI_BUSER(S_AXI_BUSER),
.S_AXI_BVALID(S_AXI_BVALID_d),
.S_AXI_BREADY(S_AXI_BREADY),
.S_AXI_ARID(S_AXI_ARID),
.S_AXI_ARADDR(S_AXI_ARADDR),
.S_AXI_ARLEN(S_AXI_ARLEN),
.S_AXI_ARSIZE(S_AXI_ARSIZE),
.S_AXI_ARBURST(S_AXI_ARBURST),
.S_AXI_ARLOCK(S_AXI_ARLOCK),
.S_AXI_ARCACHE(S_AXI_ARCACHE),
.S_AXI_ARPROT(S_AXI_ARPROT),
.S_AXI_ARREGION(S_AXI_ARREGION),
.S_AXI_ARQOS(S_AXI_ARQOS),
.S_AXI_ARUSER(S_AXI_ARUSER),
.S_AXI_ARVALID(S_AXI_ARVALID),
.S_AXI_ARREADY(S_AXI_ARREADY_d),
.S_AXI_RID(S_AXI_RID_d),
.S_AXI_RDATA(S_AXI_RDATA_d),
.S_AXI_RRESP(S_AXI_RRESP_d),
.S_AXI_RLAST(S_AXI_RLAST_d),
.S_AXI_RUSER(S_AXI_RUSER),
.S_AXI_RVALID(S_AXI_RVALID_d),
.S_AXI_RREADY(S_AXI_RREADY),
.pixclk(pixclk),
.TMDS_tx_clk_p(TMDS_tx_clk_p),
.TMDS_tx_clk_n(TMDS_tx_clk_n),
.TMDS_tx_2_G_p(TMDS_tx_2_G_p),
.TMDS_tx_2_G_n(TMDS_tx_2_G_n),
.TMDS_tx_1_R_p(TMDS_tx_1_R_p),
.TMDS_tx_1_R_n(TMDS_tx_1_R_n),
.TMDS_tx_0_B_p(TMDS_tx_0_B_p),
.TMDS_tx_0_B_n(TMDS_tx_0_B_n)
);
assign #DELAY S_AXI_AWREADY = S_AXI_AWREADY_d;
assign #DELAY S_AXI_WREADY = S_AXI_WREADY_d;
assign #DELAY S_AXI_BID = S_AXI_BID_d;
assign #DELAY S_AXI_BRESP = S_AXI_BRESP_d;
assign #DELAY S_AXI_BVALID = S_AXI_BVALID_d;
assign #DELAY S_AXI_ARREADY = S_AXI_ARREADY_d;
assign #DELAY S_AXI_RID = S_AXI_RID_d;
assign #DELAY S_AXI_RDATA = S_AXI_RDATA_d;
assign #DELAY S_AXI_RRESP = S_AXI_RRESP_d;
assign #DELAY S_AXI_RLAST = S_AXI_RLAST_d;
assign #DELAY S_AXI_RVALID = S_AXI_RVALID_d;
parameter ACLK_PERIOD = 100;
parameter real ACLK_DUTY_CYCLE = 0.5;
parameter ACLK_OFFSET = 0;
initial // Clock process for clk
begin
#ACLK_OFFSET;
forever
begin
ACLK = 1'b0;
#(ACLK_PERIOD-(ACLK_PERIOD*ACLK_DUTY_CYCLE)) ACLK = 1'b1;
#(ACLK_PERIOD*ACLK_DUTY_CYCLE);
end
end
parameter PIXCLK_PERIOD = 250;
parameter real PIXCLK_DUTY_CYCLE = 0.5;
parameter PIXCLK_OFFSET = 0;
initial // Clock process for clk
begin
#PIXCLK_OFFSET;
forever
begin
pixclk = 1'b0;
#(PIXCLK_PERIOD-(PIXCLK_PERIOD*PIXCLK_DUTY_CYCLE)) pixclk = 1'b1;
#(PIXCLK_PERIOD*PIXCLK_DUTY_CYCLE);
end
end
// Write Channel
initial begin
// Initialize Inputs
ARESETN = 0;
S_AXI_AWID = 0;
S_AXI_AWADDR = 0;
S_AXI_AWLEN = 0;
S_AXI_AWSIZE = 0;
S_AXI_AWBURST = 0;
S_AXI_AWVALID = 0;
S_AXI_AWLOCK = 0;
S_AXI_AWCACHE = 2; // Normal Non-cacheable Non-bufferable
S_AXI_AWPROT = 0;
S_AXI_AWREGION = 0;
S_AXI_AWQOS = 0;
S_AXI_AWUSER = 0;
S_AXI_WID = 0;
S_AXI_WDATA = 0;
S_AXI_WSTRB = 0;
S_AXI_WLAST = 0;
S_AXI_WUSER = 0;
S_AXI_WVALID = 0;
S_AXI_BREADY = 0;
pixclk = 0;
// Wait 100 ns for global reset to finish
#1000;
// Add stimulus here
ARESETN = 1'b1;
#5000 // 500nsec Wait
@(posedge ACLK); // 次のクロックへ
#DELAY;
AXI_Master_1Seq_Write(0, 32'h100, 8'd4, ASIZE_BT_4, ABURST_INCR, 32'h12345678, 0);
AXI_Master_1Seq_Write(0, 32'h200, 8'd0, ASIZE_BT_4, ABURST_INCR, 32'h11223344, 1);
// アドレス転送のオーバーラップのサンプル
// オーバーラップ後にもう一度、2度目のWrite Address Channel の転送を行う。
AXI_MASTER_WAC(0, 32'h300, 8'd0, ASIZE_BT_4, ABURST_INCR);
AXI_MASTER_WAC(0, 32'h400, 8'd0, ASIZE_BT_4, ABURST_INCR);
AXI_MASTER_WDC(32'h1111_2222);
AXI_MASTER_WRC(0);
AXI_MASTER_WAC(0, 32'h400, 8'd0, ASIZE_BT_4, ABURST_INCR);
AXI_MASTER_WDC(32'h3333_4444);
AXI_MASTER_WRC(0);
end
// Read Channel
initial begin
// Initialize Inputs
S_AXI_ARID = 0;
S_AXI_ARADDR = 0;
S_AXI_ARLEN = 0;
S_AXI_ARSIZE = 0;
S_AXI_ARBURST = 0;
S_AXI_ARLOCK = 0;
S_AXI_ARCACHE = 2; // Normal Non-cacheable Non-bufferable
S_AXI_ARPROT = 0;
S_AXI_ARREGION = 0;
S_AXI_ARQOS = 0;
S_AXI_ARUSER = 0;
S_AXI_ARVALID = 0;
S_AXI_RREADY = 0;
// Wait 100 ns for global reset to finish
#1000;
// Add stimulus here
#5000 // 500nsec Wait
@(posedge ACLK); // 次のクロックへ
#DELAY;
AXI_Master_1Seq_Read(0, 32'h100, 8'd4, ASIZE_BT_4, ABURST_INCR);
AXI_Master_1Seq_Read(0, 32'h200, 8'd0, ASIZE_BT_4, ABURST_INCR);
end
//
// AXI Master Bus Function Model
//
// Write Channel
task AXI_Master_1Seq_Write; // Write Address, Write Data, Write Response をシーケンシャルにオーバーラップせずに行う。
input [0:0] awid;
input [31:0] awaddr;
input [7:0] awlen;
input [2:0] awsize;
input [1:0] awburst;
input [31:0] wdata;
input [7:0] wait_clk_bready;
begin
AXI_MASTER_WAC(awid, awaddr, awlen, awsize, awburst);
AXI_MASTER_WDC(wdata);
AXI_MASTER_WRC(wait_clk_bready);
end
endtask
// Write Address Channel
task AXI_MASTER_WAC;
input [0:0] awid;
input [31:0] awaddr;
input [7:0] awlen;
input [2:0] awsize;
input [1:0] awburst;
begin
S_AXI_AWID = awid;
S_AXI_AWADDR = awaddr;
S_AXI_AWLEN = awlen;
S_AXI_AWSIZE = awsize;
S_AXI_AWBURST = awburst;
S_AXI_AWVALID = 1'b1;
if (axi_w_transaction_active == 0) begin // AXI Write トランザクションが開始されている場合は戻る
awlen_hold = awlen; // Write Data Channel のためにバースト数を取っておく
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_AWREADY) begin // S_AXI_AWREADY が1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_AWID = 0;
S_AXI_AWADDR = 0;
S_AXI_AWLEN = 0;
S_AXI_AWSIZE = 0;
S_AXI_AWBURST = 0;
S_AXI_AWVALID = 1'b0;
@(posedge ACLK); // 次のクロックへ
#DELAY;
axi_w_transaction_active = 1; // AXIトランザクション開始
end
end
endtask
// Write Data Channel
task AXI_MASTER_WDC; // WDATA は+1する
// とりあえず、WSTRBはオール1にする
input [31:0] wdata;
integer i;
begin
i = 0;
while (i<=awlen_hold) begin
S_AXI_WVALID = 1'b1;
S_AXI_WSTRB = 4'b1111;
if (i == awlen_hold)
S_AXI_WLAST = 1'b1;
else
S_AXI_WLAST = 1'b0;
S_AXI_WDATA = wdata;
wdata = wdata + 1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_WREADY) begin // S_AXI_WREADY が0の時は1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
i = i + 1;
end
S_AXI_WVALID = 1'b0;
S_AXI_WLAST = 1'b0;
S_AXI_WSTRB = 4'b0000;
end
endtask
// Write Response Channel
task AXI_MASTER_WRC; // wait_clk_bready
input [7:0] wait_clk_bready;
integer i;
begin
for (i=0; i<wait_clk_bready; i=i+1) begin
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
S_AXI_BREADY = 1'b1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_BVALID) begin // S_AXI_BVALID が1になるまでWait
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_BREADY = 1'b0;
axi_w_transaction_active = 0; // AXIトランザクション終了
end
endtask
// Read Channel
task AXI_Master_1Seq_Read; // Read Address, Read Data をシーケンシャルに行う。
input [0:0] arid;
input [31:0] araddr;
input [7:0] arlen;
input [2:0] arsize;
input [1:0] arburst;
begin
AXI_MASTER_RAC(arid, araddr, arlen, arsize, arburst);
AXI_MASTER_RDC();
end
endtask
// Read Address Channel
task AXI_MASTER_RAC;
input [0:0] arid;
input [31:0] araddr;
input [7:0] arlen;
input [2:0] arsize;
input [1:0] arburst;
begin
S_AXI_ARID = arid;
S_AXI_ARADDR = araddr;
S_AXI_ARLEN = arlen;
S_AXI_ARSIZE = arsize;
S_AXI_ARBURST = arburst;
S_AXI_ARVALID = 1'b1;
if (axi_r_transaction_active == 0) begin // AXI Read トランザクションが開始されている場合は戻る
arlen_hold =arlen; // Read Data Channel のためにバースト数を取っておく
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_ARREADY) begin // S_AXI_ARREADY が1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_ARID = 0;
S_AXI_ARADDR = 0;
S_AXI_ARLEN = 0;
S_AXI_ARSIZE = 0;
S_AXI_ARBURST = 0;
S_AXI_ARVALID = 1'b0;
@(posedge ACLK); // 次のクロックへ
#DELAY;
axi_r_transaction_active = 1; // AXIトランザクション開始
end
end
endtask
// Read Data Channel
task AXI_MASTER_RDC; // S_AXI_RLAST がアサートされるまでS_AXI_RREADY をアサートする
begin
S_AXI_RREADY = 1'b1;
@(posedge ACLK); // 次のクロックへ
while (~(S_AXI_RLAST & S_AXI_RVALID)) begin // S_AXI_RLAST & S_AXI_RVALID までS_AXI_RREADY を1にアサートする
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_RREADY = 1'b0;
axi_r_transaction_active = 0; // AXIトランザクション終了
end
endtask
endmodule
`default_nettype wire
・PLL_BASE の RESET_ON_LOSS_OF_LOCK をComponent宣言とインスタンス部分でコメントアウトした。
・BUFPLL の ENABLE_SYNC をComponent宣言とインスタンス部分でコメントアウトした。
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | - | - | - | 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 |