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

📄 serial_multiplex.vhd

📁 绝对好东西
💻 VHD
字号:
--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:    18:57:29 12/26/07
-- Design Name:    
-- Module Name:    serial_multiplex - Behavioral
-- Designed by:  Ahrong
-- E-mail: jeawen.lin@163.com
-- Revision History:
--   1.0  2005-12-28  Ahrong
--        Initial version
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity serial_multiplex is
	  generic(
		K_WIDTH : integer := 12;  --K width
		X_WIDTH : integer := 24   --X width
		);
	port (
			RST        : in  std_logic;
			CLK        : in  std_logic;
			MUL_EN     : in std_logic;
			K          : in  std_logic_vector(K_WIDTH - 1 downto 0);
			X          : in  std_logic_vector(X_WIDTH - 1 downto 0);
			Y          : out std_logic_vector(K_WIDTH + X_WIDTH-1 downto 0);	
			MUL_BUSY   : out std_logic;
			MUL_FINISH : out std_logic
	);

end serial_multiplex;

architecture Behavioral of serial_multiplex is

signal CNT : integer range 0 to K_WIDTH+2 := 0;

signal pos_K: std_logic_vector(K_WIDTH-1 downto 0);
signal pos_X: std_logic_vector(X_WIDTH-1 downto 0);
signal reg_K: std_logic_vector(K_WIDTH-1 downto 0);
signal reg_X: std_logic_vector(K_WIDTH + X_WIDTH-2 downto 0) := (others => '0');
signal SUM  : std_logic_vector(K_WIDTH + X_WIDTH-1 downto 0);

signal last_MUL_EN : std_logic ;
signal CAL_EN      : std_logic := '0';

signal state_idle           : std_logic;
signal state_input_convert  : std_logic;
signal state_initiate       : std_logic;
signal state_caculate       : std_logic;
signal state_invert         : std_logic;
signal state_finish         : std_logic;

signal cal_finish           : std_logic := '0';
signal result_sign          : std_logic := '0';

subtype state is std_logic_vector(5 downto 0);
signal	MUL_CS             : state;

constant IDLE              : state   := "000001";		  
constant INPUT_CONVERT  	: state   := "000010";		  
constant INITIATE				: state   := "000100";		  
constant CACULATE				: state   := "001000";		  
constant INVERT            : state   := "010000";
constant FINISH         	: state   := "100000";


begin


state_idle           <= MUL_CS(0);
state_input_convert  <= MUL_CS(1);
state_initiate       <= MUL_CS(2);
state_caculate       <= MUL_CS(3);
state_invert         <= MUL_CS(4);
state_finish			<= MUL_CS(5);

----------------------------------------------------------------------------------------------------
--FSM
process(CLK,RST)
begin
	if RST= '1' then
		MUL_CS <= IDLE;
	elsif rising_edge(CLK)then
		last_MUL_EN <= MUL_EN;		
		case MUL_CS is
			when IDLE =>
				if last_MUL_EN = '0' and MUL_EN = '1' then
					MUL_CS <= INPUT_CONVERT;
				 end if;
			when INPUT_CONVERT =>
				MUL_CS <= INITIATE;
			when INITIATE =>
				MUL_CS <= CACULATE;
			when CACULATE =>
				if cal_finish = '1' then
					MUL_CS <= INVERT;
				end if;
			when INVERT =>
				MUL_CS <= FINISH;
			when FINISH =>
				MUL_CS <= IDLE;
			when others =>
				MUL_CS <= IDLE;
		end case;
	end if;
end process;
--END FSM
-----------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
--process(CLK)
--begin
--	if rising_edge(CLK)then
--		if state_idle = '1' then
--			MUL_BUSY <= '0';
--		else
--			MUL_BUSY <= '1';
--		end if;
--	end if;
--end process;
MUL_BUSY <= not(state_idle);
---------------------------------------------------------------------------------------------------

----signed convert---------------------------------------------------------------------------------
process(CLK)
begin
	if rising_edge(CLK)then
	  if state_input_convert = '1' then

	  	   result_sign <= K(K_WIDTH-1) xor X(X_WIDTH-1);

	  		if K(K_WIDTH-1) = '1' then
				pos_K <= not(K)+1;
			else
				pos_K <= K;
			end if;

			if X(X_WIDTH-1) = '1' then
				pos_X <= not(X) + 1;
			else
				pos_X <= X;
			end if;
	  end if;

	end if;
end process;
---------------------------------------------------------------------------------------------------

--caculate-------------------------------------------------------------------------------------------------
process(CLK,RST)
begin
	if RST = '1' then
		reg_X <= (others => '0');
		SUM(K_WIDTH + X_WIDTH-1 downto 0)   <= (others => '0');
	elsif rising_edge(CLK) then
		if state_initiate = '1' then
			reg_K <= pos_K;
			reg_X <= reg_X + pos_X;
			SUM(K_WIDTH + X_WIDTH-1 downto 0)   <= (others => '0');
			CNT <= 0;
			cal_finish <= '0';
		elsif state_caculate = '1' then
			CNT <= CNT+1;
			if CNT < K_WIDTH then
				reg_K(K_WIDTH-1 downto 0) <= '0' & reg_K(K_WIDTH-1 downto 1);
				reg_X(K_WIDTH + X_WIDTH-2 downto 0) <= reg_X(K_WIDTH + X_WIDTH-3 downto 0) & '0';
				if reg_K(0)= '1' then
					SUM(K_WIDTH + X_WIDTH-1 downto 0 ) <= SUM(K_WIDTH + X_WIDTH-1 downto 0) + reg_X(K_WIDTH + X_WIDTH-2 downto 0);
				end if;
			else
				cal_finish <= '1';
				reg_X <= (others => '0');
			end if;
		end if;
	end if;
end process;
----------------------------------------------------------------------------------------------------

--output result---------------------------------------------------------------------------------------------
process(CLK)
begin
	if rising_edge(CLK)then
		if state_invert = '1' then
			if result_sign = '1' then
				Y <= not(SUM) + 1;
			else
				Y <= SUM;
			end if;		
		end if; 
	end if;
end process;

MUL_FINISH <= state_finish;
----------------------------------------------------------------------------------------------------


end Behavioral;

⌨️ 快捷键说明

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