micro_tb.vhd
来自「可编程器件厂商Xilinx的用于设计SMBus 控制器的源程序」· VHDL 代码 · 共 729 行 · 第 1/2 页
VHD
729 行
cycle <= cycle + 1;
go <= '1';
wait until clk'event and clk = '1';
wait until clk'event and clk = '1';
go <= '0';
wait until done = '1';
-- generate STOP
cycle <= cycle + 1;
wait until mcf = '1';
go <= '1';
wait until clk'event and clk = '1';
wait until clk'event and clk = '1';
go <= '0';
wait until done = '1';
-- Beginning of Repeated START test
-- now read the status registers
write <= '0';
for i in 0 to 2 loop
cycle <= cycle + 1;
go <= '1';
wait until clk'event and clk = '1';
wait until clk'event and clk = '1';
go <= '0';
wait until done = '1';
end loop;
-- The loop below writes the registers, sets the SMBUS header and
-- generates the START signal for a master transmit/slave receive cycle
write <= '1';
for i in 0 to 2 loop
cycle <= cycle + 1;
go <= '1';
wait until clk'event and clk ='1';
wait until clk'event and clk = '1';
go <= '0';
wait until done = '1';
end loop;
-- wait for MCF to indicate that transfer is complete
-- then write one data byte to master's data register for transfer over SMBUS
cycle <= cycle + 1;
wait until mcf = '1';
go <= '1';
wait until clk'event and clk = '1';
wait until clk'event and clk = '1';
go <= '0';
wait until done = '1';
-- wait for MCF to indicate that transfer is complete
-- then set the SMBUS header indicating slave read and
-- generates the REPEATED START signal for a slave transmit/master receive cycle
wait until mcf = '1';
for i in 0 to 2 loop
cycle <= cycle + 1;
go <= '1';
wait until clk'event and clk = '1';
wait until clk'event and clk = '1';
go <= '0';
wait until done = '1';
end loop;
-- wait for MCF to indicate that transfer is complete
-- then write data to to slave's data register for transfer over SMBUS
for i in 1 to 6 loop
cycle <= cycle + 1;
wait until mcf = '1';
go <= '1';
wait until clk'event and clk = '1';
wait until clk'event and clk = '1';
go <= '0';
wait until done = '1';
end loop;
-- turn off Master's ACK
-- wait for MCF to negate again to insure no longer in ACK state
wait until mcf = '0';
cycle <= cycle + 1;
go <= '1';
wait until clk'event and clk = '1';
wait until clk'event and clk = '1';
go <= '0';
wait until done = '1';
-- generate STOP
cycle <= cycle + 1;
wait until mcf = '1';
go <= '1';
wait until clk'event and clk = '1';
wait until clk'event and clk = '1';
go <= '0';
wait until done = '1';
wait;
end process;
-- *********************************** SH7750 State Machine Processes *********************************
-- Define the synchronous process of the state machines
-- the outputs get the value from the state machine
-- WE_N changes on the falling edge of the clock and therefore in a separate process
ffs: process(reset, clk)
begin
if reset = RESET_ACTIVE then
state <= IDLE;
elsif clk'event and (clk = '1') then
state <= next_state;
end if;
end process;
ffs_neg: process(reset, clk)
begin
if reset = RESET_ACTIVE then
we_n <= '1';
elsif clk'event and (clk = '0') then
we_n <= wen_com;
end if;
end process;
-- Synthesize uProc bus protocol
-- create rd_wrn signal
rd_wrn <= not (write);
-- OR together the master ready and slave ready signals
--rdy_n <= '0' when (master_rdyn = '0') or (slave_rdyn = '0')
--else '1';
rdy_n <= '0';
sh7750_sm: process(state, go, write, rdy_n, cnt)
--variable cnt : unsigned(3 downto 0) := "0000";
begin
next_state <= state;
done <= '1';
bs_n <= '1';
master_cs_n <= '1';
slave_cs_n <= '1';
rd_n <= '1';
wen_com <= '1';
oe <= '0';
address <= (others => '0');
data_out <= (others => '0');
data_in <= (others => '0');
cnt_en <= '0'; -- initialize counter enable to inactive state
cnt_rst <= RESET_ACTIVE; -- initialize counter reset to inactive state
case state is
-------------- IDLE State -----------------
when IDLE =>
if go = '1' then
if SETUP_STATES = 0 then
next_state <= T1; -- no setup states
else
next_state <= Tsetup;
end if;
end if;
------------ Tsetup State -------------------
when Tsetup =>
-- setup states
bs_n <= '0';
if TST_ADDR_OUT(cycle)(23 downto 8) = MASTR_MBASE then
master_cs_n <= '0';
elsif TST_ADDR_OUT(cycle)(23 downto 8) = SLAVE_MBASE then
slave_cs_n <= '0';
end if;
address <= TST_ADDR_OUT(cycle)(7 downto 0);
cnt_en <= '1';
cnt_rst <= not(RESET_ACTIVE);
if cnt = SETUP_STATES -1 then -- if enough wait states, move on
next_state <= T1;
end if;
done <= '0';
----------- T1 State --------------
when T1 =>
-- if there was a setup state, bs_n is asserted in the setup state
-- don't assert it in this state. If there isn't a setup state,
-- assert bs_n
if SETUP_STATES = 0 then
-- no setup state, assert bs_n
bs_n <= '0';
end if;
if TST_ADDR_OUT(cycle)(23 downto 8) = MASTR_MBASE then
master_cs_n <= '0';
elsif TST_ADDR_OUT(cycle)(23 downto 8) = SLAVE_MBASE then
slave_cs_n <= '0';
end if;
address <= TST_ADDR_OUT(cycle)(7 downto 0);
if write = '1' then
wen_com <= '0';
end if;
if WAIT_STATES = 0 then
next_state <= T2; -- no wait states
else
next_state <= Tw; -- wait states
end if;
done <= '0';
------------ Tw State ---------------
when Tw =>
-- wait state
-- output chip select, address, and control signals
if TST_ADDR_OUT(cycle)(23 downto 8) = MASTR_MBASE then
master_cs_n <= '0';
elsif TST_ADDR_OUT(cycle)(23 downto 8) = SLAVE_MBASE then
slave_cs_n <= '0';
end if;
address <= TST_ADDR_OUT(cycle)(7 downto 0);
if write = '1' then
wen_com <= '0';
oe <= '1';
data_out <= TST_DATA_OUT(cycle);
else
rd_n <= '0';
end if;
cnt_rst <= not(RESET_ACTIVE);
cnt_en <= '1';
-- see if device is ready for data transfer in T2 state
if rdy_n = '0' and cnt = WAIT_STATES -1 then
next_state <= T2;
end if;
done <= '0';
------------ T2 State ---------------
when T2 =>
if TST_ADDR_OUT(cycle)(23 downto 8) = MASTR_MBASE then
master_cs_n <= '0';
elsif TST_ADDR_OUT(cycle)(23 downto 8) = SLAVE_MBASE then
slave_cs_n <= '0';
end if;
address <= TST_ADDR_OUT(cycle)(7 downto 0);
if write = '1' then
oe <= '1';
data_out <= TST_DATA_OUT(cycle);
if HOLD_STATES = 0 then
next_state <= IDLE;
else
next_state <= Thold;
end if;
else
rd_n <= '0';
next_state <= DATA_TRS;
end if;
done <= '0';
------------ DATA_TRS State ---------------
when DATA_TRS =>
if TST_ADDR_OUT(cycle)(23 downto 8) = MASTR_MBASE then
master_cs_n <= '0';
elsif TST_ADDR_OUT(cycle)(23 downto 8) = SLAVE_MBASE then
slave_cs_n <= '0';
end if;
address <= TST_ADDR_OUT(cycle)(7 downto 0);
data_in <= data_bus; -- latch data on clock after rd_n
if HOLD_STATES = 0 then
-- no hold states required, go to IDLE
next_state <= IDLE;
elsif HOLD_STATES = 1 then
next_state <= IDLE; -- this state counts as 1 hold state
rd_n <= '0';
else -- hold states
rd_n <= '0';
cnt_en <= '1';
cnt_rst <= not(RESET_ACTIVE); -- count this state as a hold state
next_state <= Thold;
end if;
done <= '0';
--------------- THOLD State -----------------
when Thold =>
if TST_ADDR_OUT(cycle)(23 downto 8) = MASTR_MBASE then
master_cs_n <= '0';
elsif TST_ADDR_OUT(cycle)(23 downto 8) = SLAVE_MBASE then
slave_cs_n <= '0';
end if;
address <= TST_ADDR_OUT(cycle)(7 downto 0);
if write = '1' then
-- write cycle
oe <= '1';
data_out <= TST_DATA_OUT(cycle);
end if;
cnt_en <= '1';
cnt_rst <= not(RESET_ACTIVE);
if cnt = HOLD_STATES -1 then -- no more hold states
next_state <= IDLE;
end if;
done <= '0';
end case;
end process;
-- Counter process
upcnt: process(clk, cnt_rst)
begin
-- Clear output register
if (cnt_rst = RESET_ACTIVE) then
cnt <= (others => '0');
-- On rising edge of clock count
elsif (clk'event) and clk = '1' then
if cnt_en = '1' then
cnt <= cnt + 1;
end if;
end if;
end process;
end RTL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?