?? serial_multiplex.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 + -