git-svn-id: http://moon:8086/svn/vhdl/trunk@1429 cc03376c-175c-47c8-b038-4cd826a8556b
184 lines
4.4 KiB
VHDL
184 lines
4.4 KiB
VHDL
library IEEE;
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
use IEEE.STD_LOGIC_ARITH.ALL;
|
|
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
|
|
|
-- Uncomment the following lines to use the declarations that are
|
|
-- provided for instantiating Xilinx primitive components.
|
|
--library UNISIM;
|
|
--use UNISIM.VComponents.all;
|
|
|
|
entity vconfig is
|
|
Port ( RES : in std_logic;
|
|
nINIT_B : in std_logic;
|
|
CLK : in std_logic;
|
|
DONE : in std_logic;
|
|
CCLK : out std_logic;
|
|
CCLK_PRESCALER : in std_logic_vector(5 downto 0);
|
|
LOAD_PRESCALER : in std_logic;
|
|
DIN : in std_logic_vector(31 downto 0);
|
|
DOUT : out std_logic;
|
|
LOAD_SREG : in std_logic;
|
|
BUF_IS_EMPTY : inout std_logic);
|
|
end vconfig;
|
|
|
|
architecture Behavioral of vconfig is
|
|
|
|
constant nbits : integer := 32;
|
|
constant nBufs : integer := 2;
|
|
|
|
type t_config_state is (CFG_STOP, CFG_INIT, CFG_RUN);
|
|
type t_buf is array (0 to nBufs-1) of std_logic_vector (nBits-1 downto 0);
|
|
|
|
signal REG: t_buf;
|
|
signal count, CLK_SCALE: integer range 0 to 63;
|
|
signal SHIFT_CNT: integer range 0 to nbits-1;
|
|
signal state, next_state : t_config_state;
|
|
signal SCLK, SHIFT_EN : STD_LOGIC;
|
|
signal buf_depth: integer range 0 to 2;
|
|
signal tempID, readBufId, writeBufId : integer range 0 to nBufs-1;
|
|
|
|
|
|
begin
|
|
|
|
-- 4-bit loadable serial-in and serial-out shift register
|
|
-- CLK: in STD_LOGIC;
|
|
-- DIN: in STD_LOGIC;
|
|
-- LOAD: in STD_LOGIC;
|
|
-- LOAD_DATA: in STD_LOGIC_VECTOR(3 downto 0);
|
|
-- DOUT: out STD_LOGIC;
|
|
|
|
|
|
process (RES, SCLK, state, nINIT_B, DONE, REG, BUF_IS_EMPTY)
|
|
begin
|
|
if (RES = '1') then
|
|
CCLK <= '1';
|
|
SHIFT_EN <= '0';
|
|
DOUT <= 'Z';
|
|
|
|
else
|
|
case state is
|
|
when CFG_STOP =>
|
|
SHIFT_EN <= '0';
|
|
CCLK <= '1';
|
|
if (DONE = '0' and BUF_IS_EMPTY = '0') then
|
|
next_state <= CFG_INIT;
|
|
else
|
|
next_state <= CFG_STOP;
|
|
end if;
|
|
|
|
when CFG_INIT =>
|
|
CCLK <= SCLK;
|
|
next_state <= CFG_RUN;
|
|
|
|
when CFG_RUN =>
|
|
SHIFT_EN <= '1';
|
|
CCLK <= SCLK;
|
|
if (DONE = '1' or nINIT_B = '0' or BUF_IS_EMPTY = '1') then
|
|
next_state <= CFG_STOP;
|
|
else
|
|
next_state <= CFG_RUN;
|
|
end if;
|
|
end case;
|
|
if (nINIT_B = '1') then
|
|
DOUT <= STD_LOGIC(REG(readBufId)(nbits-1));
|
|
else
|
|
DOUT <= 'Z';
|
|
end if;
|
|
end if;
|
|
|
|
end process;
|
|
|
|
sreg:
|
|
process(RES, SCLK, REG, DIN, LOAD_SREG, SHIFT_EN, SHIFT_CNT)
|
|
begin
|
|
if (RES = '1') then
|
|
BUF_IS_EMPTY <= '1';
|
|
SHIFT_CNT <= 0;
|
|
writeBufId <= 0;
|
|
readBufId <= 0;
|
|
buf_depth <= 0;
|
|
|
|
elsif (LOAD_SREG = '1') then
|
|
REG(writeBufId) <= DIN;
|
|
|
|
if (SHIFT_EN = '0') then
|
|
SHIFT_CNT <= nbits-1;
|
|
end if;
|
|
|
|
if (buf_depth = nbufs) then
|
|
buf_depth <= buf_depth ;
|
|
else
|
|
buf_depth <= buf_depth + 1;
|
|
end if;
|
|
|
|
else
|
|
if SCLK='0' and SCLK'event then
|
|
if SHIFT_EN = '1' then
|
|
REG(readBufId)(nbits-1 downto 0) <= REG(readBufId)(nbits-2 downto 0) & '0';
|
|
if (SHIFT_CNT = 0) then
|
|
if (buf_depth = 0) then
|
|
writeBufId <= 0;
|
|
readBufId <= 0;
|
|
else
|
|
SHIFT_CNT <= nbits-1;
|
|
tempID <= readBufID;
|
|
readBufID <= writeBufId;
|
|
writeBufId <= tempID;
|
|
buf_depth <= buf_depth - 1;
|
|
end if;
|
|
else
|
|
SHIFT_CNT <= SHIFT_CNT - 1;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
if (SHIFT_CNT = 0 and buf_depth = 1) then
|
|
BUF_IS_EMPTY <= '1';
|
|
else
|
|
BUF_IS_EMPTY <= '0';
|
|
end if;
|
|
end process;
|
|
|
|
-- 4-bit synchronous counter with count enable,
|
|
-- asynchronous reset
|
|
-- CLK: in STD_LOGIC;
|
|
-- RESET: in STD_LOGIC;
|
|
-- CE, LOAD, DIR: in STD_LOGIC;
|
|
-- DIN: in STD_LOGIC_VECTOR(3 downto 0);
|
|
-- COUNT: inout STD_LOGIC_VECTOR(3 downto 0);
|
|
cfg_state_gen:
|
|
process(RES, SCLK, next_state)
|
|
begin
|
|
if (RES = '1') then
|
|
state <= CFG_STOP;
|
|
elsif SCLK='1' and SCLK'event then
|
|
state <= next_state;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
clk_prescaler:
|
|
process (RES, CLK, CCLK_PRESCALER, LOAD_PRESCALER)
|
|
begin
|
|
if (RES = '1') then
|
|
SCLK <= '1';
|
|
CLK_SCALE <= 1;
|
|
COUNT <= CLK_SCALE;
|
|
|
|
elsif (LOAD_PRESCALER = '1') then
|
|
CLK_SCALE <= CONV_INTEGER(CCLK_PRESCALER);
|
|
|
|
elsif CLK='1' and CLK'event then
|
|
if (COUNT = 1) then
|
|
SCLK <= not SCLK;
|
|
|
|
COUNT <= CLK_SCALE;
|
|
else
|
|
COUNT <= COUNT - 1;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
end Behavioral;
|