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 + -
显示快捷键?