📄 uc_interface_tb.vhd
字号:
-- *********************************** 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 + -