⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uc_interface_tb.vhd

📁 8051接口VHDL代码
💻 VHD
📖 第 1 页 / 共 3 页
字号:
-- *********************************** uC Process *********************************
--  Synthesize uProc bus protocol
UCBUS: process
begin

    -- Set up defaults
    uc_done <= '1';
    ad_oe <= '0';
    ale_n <= '1';
    psen_n <= '1';
    addr <= (others => '0');
    ad_out <= (others => '0');
    ucdata_in_ce <= '0';
    wr_n <= '1';
    rd_n <= '1';
    
    -- Wait for go to assert
    wait until go'event and go = '1';
    
    -- start bus cycle
    uc_done <= '0';
    
    -- wait part of ALE_N negation cycle (ALE_N pulse width - address setup time)
    wait for TLHLL - TAVLL;
    
    -- setup address on busses
    addr <= uc_addr(15 downto 8);
    ad_out <= uc_addr(7 downto 0);
    ad_oe <= '1';
    
    -- wait address setup time then assert ALE_N
    wait for TAVLL;
    ale_n <= '0';
    
    
    
    -- determine if this is a program store cycle, write cycle, or read cycle
    if assert_psen = '1' then
        -- program store cycle
    
        -- wait before asserting PSEN_N
        wait for TLLPL;
        psen_n <= '0';
        
        -- wait address hold time then tri-state
        wait for TPLAZ;
        ad_oe <= '0';       -- tri-state ad bus
        
        -- wait for instruction access time then capture data
        -- by asserting clock enable for input data register
        wait for TPLIV;
        ucdata_in_ce <= '1';
        
        -- wait remainder of PSEN_N pulse width then negate PSEN_N and ALE_N
        -- and negate clock enable for input data register
        wait for TPLPH - TPLIV;
        psen_n <= '1';
        ale_n <= '1';
        ucdata_in_ce <= '0';
    
    elsif write = '1' then
        -- write cycle
        -- wait address hold time
        wait for TLLAX;
        
        -- write cycle, put data on ad
        ad_oe <= '1';
        ad_out <= uc_data;
        
        -- wait data setup time then assert WR_N
        wait for TQVWX;
        wr_n <= '0';
        
        -- wait write pulse width then negate WR_N
        wait for TWLWH;
        wr_n <= '1';
        
        -- wait data hold time after WR_N then remove data
        wait for TWHQX;
        ad_oe <= '0';
        
        -- wait remaining ALE_N hold time after WR_N then negate ALE_N
        wait for TWHLH - TWHQX;
        ale_n <= '1';
    
    else
        -- read cycle
        -- wait address hold time
        wait for TLLAX;
        ad_oe <= '0';
        
        -- read cycle, wait address Z time before asserting RD_N
        wait for TRLAZ;
        rd_n <= '0';
        
        -- wait for data to be valid, then capture it
        -- by asserting clock enable for input data register
        wait for TRLDV;
        ucdata_in_ce <= '1';
        
        -- wait remainding time in read pulse then negate RD_N
        -- by negating clock enable for input data register 
        wait for TRLRH - TRLDV;
        rd_n <= '1';
        ucdata_in_ce <= '0';
        
        -- wait ALE_N hold time then negate ALE_N;
        wait for TWHLH;
        ale_n <= '1';
    end if;
    
    -- signify end of bus cycle by asserting UC_DONE
    uc_done <= '1';
    
    -- process will now return to beginning to wait for GO
end process;

-- *********************************** Input Register Process *********************************
-- This process captures data from the ADDR_DATA bus during read and program store bus cycles
-- Data is clocked into the register when the clock enable is asserted from the uC bus cycle
-- process
INPUT_REGS: process(reset, clk)
begin
    if reset = RESET_ACTIVE then
        ucdata_in <= (others => '0');
    elsif clk'event and clk = '1' then
        if ucdata_in_ce = '1' then
            ucdata_in <= addr_data;
        else
            ucdata_in <= ucdata_in;
        end if;
    end if;
end process;

-- *************************************************************************************************
-- *********************************** Application Logic Processes *********************************
-- *************************************************************************************************
-- These processes mock up the application logic by providing data to load into the output data
-- register,and asserting the DATA_RDY and NEED_DATA flags. These processes will operate on a
-- divided version of the system clock
--
-- NOTE: when the real application logic is available, these processes should be removed.


-- ************************** Need Data Flag Assertion Process ***********************************
-- The NEEDDATA_PROCESS assumes that the application logic will grab the first data in the 
-- input data register APP_FIRST_WORD_ACCESS clocks after the APP_EN asserts and then waits the 
-- number of clocks required for the application logic to "work" on the data, APP_WORK_DATA_CLKS,
-- before requesting new data. Therefore, this process asserts the NEED_DATA flag APP_FIRST_WORD_ACCESS
-- clocks after APP_EN asserts. It then asserts the NEED_DATA flag every APP_WORK_DATA_CLKS clocks 
-- after that, assuming that the application logic requires APP_WORK_DATA_CLKS clocks to "work" on the data.
NEEDDATA_PROCESS: process(reset, clk, need_data_reset) 
begin
    if reset = RESET_ACTIVE or need_data_reset = RESET_ACTIVE then
        need_data <= '0';
    elsif clk'event and clk = '1' then
        if app_en = '1' and start = '1' then
            if first_loop = '1' and clk_cnt = APP_FIRST_WORD_ACCESS then
                need_data <= '1';
                first_loop <= '0';
            elsif clk_cnt = APP_WORK_DATA_CLKS then
                need_data <= '1';
            end if;
        end if;
    end if;
end process;

CLKCNT_PROCESS: process(reset, clk)
begin
    if reset = RESET_ACTIVE then
        clk_cnt <= 0;
    elsif clk'event and clk = '1' then
        if ((clk_cnt = APP_FIRST_WORD_ACCESS and first_loop = '1') 
            or (clk_cnt = APP_WORK_DATA_CLKS and first_loop = '0')) then
            clk_cnt <= 0;
        else
            clk_cnt <= clk_cnt + 1;
        end if;
    end if;
end process;

-- ************************** Output Data Process ***********************************
-- The OUTPUTDATA_PROCESS assumes that the application logic will provide data to the 
-- output data register every APP_WORK_DATA_CLKS clocks after the APP_EN asserts.
-- Therefore, this process asserts the DATAOUT_LOAD and DONE signals and assigns data
-- to the APP_DATA bus every 16 clocks after APP_EN asserts while START is asserted. 

OUTPUTDATA_PROCESS: process

variable i,j : integer := 0;

begin

    -- initialize load signal and data
    dataout_load <= '0';
    app_data <= (others => '0');
    done <= '0';
    
    -- wait for application logic to be enabled
    wait until app_en = '1';
    
    -- wait for start signal to be asserted
    wait until start = '1';
        
    -- every APP_WORK_DATA_CLKS clocks, assert DATA_RDY, DATAOUT_LOAD, and send out data
    -- from the EXPECTED DATA array
    while app_en = '1' loop
        for i in 1 to APP_WORK_DATA_CLKS loop
            wait until clk'event and clk = '1';
            if i = 2 then
                -- negate dataout_load 1 clock after expected data was output
                -- negate done as well
                dataout_load <= '0';
                done <= '0';
            end if;
        end loop;
        dataout_load <= '1';
        done <= '1';
        app_data <= EXPECTED_DATA(j);
        if j = 3 then
            j := 0;
        else
            j := j + 1;
        end if;
           
    end loop;
    
end process;

-- ************************** Data Ready Process ***********************************   
-- The DATARDY_PROCESS asserts DATA_RDY whenever the DATAOUT_LOAD signal asserts while
-- START and APP_EN = 1. It negates when DATA_RDY_RESET is asserted.

DATARDY_PROCESS: process (clk, reset, data_rdy_reset)
 
begin     
      if reset = RESET_ACTIVE or data_rdy_reset = RESET_ACTIVE then
        data_rdy <= '0';
      elsif clk'event and clk = '1' then
            if dataout_load = '1' and app_en = '1' then
                    -- assert data rdy flag when data is loaded into output data register
                    -- if application logic has been enabled and start is still 1
                    data_rdy <= '1';
            end if;
      end if;
end process;

-- *********************************** ERROR Process *********************************
-- This process will asynchronously assert ERROR as determined by the constant ERROR_ASSERT_TIME.
-- If this time is set to 0, then ERROR will never be asserted. This allows the testbench to be
-- run without interference of this signal
ERROR_PROC: process

begin
    error <= '0';
    if ERROR_ASSERT_TIME = 0 uS then
        wait;
    else
        wait for ERROR_ASSERT_TIME;
        error <= '0';
        wait for ERROR_ASSERT_TIME;
        error <= '1';
        wait;
    end if;
end process;    

END;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -