- Intital revision

git-svn-id: http://moon:8086/svn/vhdl/trunk@133 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2008-11-01 21:48:26 +00:00
parent 755b318e7a
commit 5091040c1d
16 changed files with 2089 additions and 0 deletions
+351
View File
@@ -0,0 +1,351 @@
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY ac97_wb IS
Generic
(
fifo_depth : natural := 4
);
Port
(
-- J-Bus domain
CLK_I : in STD_LOGIC;
RST_I : in STD_LOGIC;
CYC_I : in STD_LOGIC;
STB_I : in STD_LOGIC;
WE_I : in STD_LOGIC;
ACK_O : out STD_LOGIC;
SRDY_O : out STD_LOGIC;
MRDY_I : in STD_LOGIC;
ADDR_I : in unsigned(31 downto 0);
DAT_I : in unsigned(31 downto 0);
DAT_O : out unsigned(31 downto 0);
INT_O : out STD_LOGIC;
-- AC97 domain
ac97_sdata_in : in std_logic;
ac97_bit_clk : in std_logic;
ac97_reset_n : out std_logic;
ac97_sdata_out : out std_logic;
ac97_ssync : out std_logic
);
END ac97_wb;
ARCHITECTURE behavior OF ac97_wb IS
constant ac_data_width : natural := 20;
constant pcm_data_width : natural := 18;
constant stat_data_width : natural := 16;
signal cmd_reg_we : std_logic;
signal cmd_pending : std_logic;
signal ac_cmd_data : unsigned(ac_data_width-1 downto 0);
signal ac_cmd_addr : unsigned(ac_data_width-1 downto 0);
signal ac_cmd_we : std_logic;
signal ac_tx_pcm_we : std_logic;
signal stat_reg : unsigned(stat_data_width-1 downto 0);
signal stat_reg_re : std_logic;
signal stat_valid : std_logic;
signal stat_pending : std_logic;
signal ac_stat_data : unsigned(ac_data_width-1 downto 0);
signal ac_stat_addr : unsigned(ac_data_width-1 downto 0);
signal ac_stat_read : std_logic;
signal ac_stat_valid : std_logic;
signal ac_tx_pcm_data : unsigned(ac_data_width-1 downto 0);
signal ac_tx_pcm_addr : unsigned (3 downto 0);
signal ac_rx_pcm_data : unsigned(ac_data_width-1 downto 0);
signal ac_rx_pcm_addr : unsigned (3 downto 0);
signal ac_sync_strobe : unsigned(0 to 2);
signal ac_slot_valid : unsigned(0 to 12);
signal ac_ready : std_logic;
signal rx_frame_valid : std_logic;
signal sync_frame : std_logic;
signal sync_tx : std_logic;
signal sync_status : std_logic;
signal request : unsigned(3 to 12);
signal tx_data_start : std_logic;
signal tx_fifo_din : unsigned(pcm_data_width-1 downto 0);
signal tx_fifo_dout : unsigned(pcm_data_width-1 downto 0);
signal tx_fifo_re : std_logic;
signal tx_fifo_we : std_logic;
signal tx_fifo_full : std_logic;
signal tx_fifo_empty : std_logic;
signal tx_fifo_almost_full : std_logic;
signal tx_fifo_almost_empty : std_logic;
signal rx_data_start : std_logic;
signal rx_fifo_din : unsigned(pcm_data_width-1 downto 0);
signal rx_fifo_dout : unsigned(pcm_data_width-1 downto 0);
signal rx_fifo_re : std_logic;
signal rx_fifo_we : std_logic;
signal rx_fifo_full : std_logic;
signal rx_fifo_empty : std_logic;
signal rx_fifo_almost_full : std_logic;
signal rx_fifo_almost_empty : std_logic;
signal ac97_stat : unsigned(31 downto 0);
signal addr_reg : unsigned(31 downto 0);
signal data_reg : unsigned(31 downto 0);
signal int_en_frame_sync : std_logic;
signal int_en_rx : std_logic;
signal int_en_tx : std_logic;
function GetRequest(slot1 : unsigned) return unsigned is
variable res : unsigned(3 to 12);
begin
res := (others => '0');
for i in res'range loop
res(i) := not slot1(14-i);
end loop;
return res;
end GetRequest;
begin
SRDY_O <= CYC_I;
INT_O <= (rx_fifo_almost_full and int_en_rx) or (tx_fifo_almost_empty and int_en_tx) or (sync_frame and int_en_frame_sync) ;
rx_frame_valid <= ac_slot_valid(0);
sync_frame <= ac_sync_strobe(0);
sync_status <= ac_sync_strobe(1);
sync_tx <= ac_sync_strobe(2);
request <= GetRequest(ac_stat_addr);
ac_stat_read <= not addr_reg(9);
ac_stat_valid <= '1' when (sync_status = '1' and ac_slot_valid(0 to 2) = "111") else '0';
ac97_stat <= ac_ready & "000" & X"00000" & '0' & int_en_rx & int_en_tx & int_en_frame_sync & not rx_fifo_almost_empty & tx_fifo_almost_full & stat_valid & cmd_pending;
command_logic:
process (CLK_I)
begin
if rising_edge(CLK_I) then
ac_cmd_we <= '0';
if RST_I = '1' then
cmd_pending <= '0';
elsif cmd_reg_we = '1' and cmd_pending = '0' then
cmd_pending <= '1';
elsif (rx_frame_valid and sync_tx) = '1' and cmd_pending = '1' then
ac_cmd_we <= '1';
cmd_pending <= '0';
end if;
end if;
end process;
status_logic:
process (CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
stat_pending <= '0';
elsif cmd_reg_we = '1' and cmd_pending = '0' then
stat_pending <= ac_stat_read;
elsif ac_stat_valid = '1' then
stat_pending <= '0';
end if;
end if;
end process;
command_register:
process (CLK_I)
begin
if rising_edge(CLK_I) then
if cmd_reg_we = '1' and cmd_pending = '0' then
ac_cmd_addr <= ac_stat_read & addr_reg(8 downto 2) & X"000";
ac_cmd_data <= data_reg(stat_data_width-1 downto 0) & X"0";
end if;
end if;
end process;
status_register:
process (CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
stat_valid <= '0';
elsif stat_pending = '1' and ac_stat_valid = '1' then
stat_reg <= ac_stat_data(ac_data_width-1 downto ac_data_width-stat_data_width);
stat_valid <= '1';
elsif stat_reg_re = '1' then
stat_valid <= '0';
end if;
end if;
end process;
-- Instantiate synchronous FIFO
inst_tx_fifo: entity work.fifo_sync_dist
GENERIC MAP
(
addr_width => fifo_depth,
data_width => pcm_data_width,
almost_full_thresh => 12,
almost_empty_thresh => 4
)
PORT MAP
(
rst => RST_I,
clk => CLK_I,
we => tx_fifo_we,
re => tx_fifo_re,
fifo_full => tx_fifo_full,
fifo_empty => tx_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => tx_fifo_din,
data_r => tx_fifo_dout
);
tx_logic:
process (CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
ac_tx_pcm_addr <= "0011";
tx_data_start <= '0';
elsif sync_tx = '1' and (request(3) and request(4)) = '1' then
ac_tx_pcm_addr <= "0011";
tx_data_start <= '1';
elsif ac_tx_pcm_addr /= "0100" then
ac_tx_pcm_addr <= ac_tx_pcm_addr + 1;
else
tx_data_start <= '0';
end if;
end if;
end process;
ac_tx_pcm_we <= not tx_fifo_empty and tx_data_start;
tx_fifo_re <= ac_tx_pcm_we;
tx_fifo_din <= data_reg(pcm_data_width-1 downto 0);
-- Instantiate synchronous FIFO
inst_rx_fifo: entity work.fifo_sync_dist
GENERIC MAP
(
addr_width => fifo_depth,
data_width => pcm_data_width,
almost_full_thresh => 12,
almost_empty_thresh => 4
)
PORT MAP
(
rst => RST_I,
clk => CLK_I,
we => rx_fifo_we,
re => rx_fifo_re,
fifo_full => rx_fifo_full,
fifo_empty => rx_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => rx_fifo_din,
data_r => rx_fifo_dout
);
rx_fifo_din <= ac_rx_pcm_data(ac_data_width-1 downto ac_data_width-pcm_data_width);
rx_logic:
process (CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
ac_rx_pcm_addr <= "0011";
rx_data_start <= '0';
elsif (rx_frame_valid and sync_frame) = '1' and (ac_slot_valid(3) and ac_slot_valid(4)) = '1' then
ac_rx_pcm_addr <= "0011";
rx_data_start <= '1';
elsif ac_rx_pcm_addr /= "0100" then
ac_rx_pcm_addr <= ac_rx_pcm_addr + 1;
else
rx_data_start <= '0';
end if;
end if;
end process;
rx_fifo_we <= rx_data_start;
inst_ac_io : entity work.ac_io
PORT MAP
(
rst => RST_I,
clk => CLK_I,
ready => ac_ready,
sync_strobe => ac_sync_strobe,
slot_valid => ac_slot_valid,
stat_addr => ac_stat_addr,
stat_data => ac_stat_data,
rx_pcm_addr => ac_rx_pcm_addr,
rx_pcm_data => ac_rx_pcm_data,
cmd_addr => ac_cmd_addr,
cmd_data => ac_cmd_data,
cmd_we => ac_cmd_we,
tx_pcm_addr => ac_tx_pcm_addr,
tx_pcm_data => ac_tx_pcm_data,
tx_pcm_we => ac_tx_pcm_we,
ac_sdata_in => ac97_sdata_in,
ac_bit_clk => ac97_bit_clk,
ac_reset_n => ac97_reset_n,
ac_sdata_out => ac97_sdata_out,
ac_ssync => ac97_ssync
);
ac_tx_pcm_data <= tx_fifo_dout & (ac_data_width-pcm_data_width-1 downto 0 => '0');
slave_data_out:
process (CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
int_en_frame_sync <= '0';
int_en_rx <= '0';
int_en_tx <= '0';
else
DAT_O <= (others => '-');
rx_fifo_re <= '0';
tx_fifo_we <= '0';
stat_reg_re <= '0';
cmd_reg_we <= '0';
ACK_O <= '0';
if (STB_I and CYC_I) = '1' then
ACK_O <= not WE_I;
case ADDR_I(11 downto 10) is
when "00" =>
DAT_O <= ac97_stat;
if WE_I = '1' then
int_en_frame_sync <= DAT_I(0);
int_en_tx <= DAT_I(1);
int_en_rx <= DAT_I(2);
end if;
when "01" =>
addr_reg <= ADDR_I;
data_reg <= DAT_I;
stat_reg_re <= not WE_I;
cmd_reg_we <= WE_I;
DAT_O <= (31 downto stat_data_width => '0') & stat_reg;
when "10" =>
addr_reg <= ADDR_I;
data_reg <= DAT_I;
rx_fifo_re <= not WE_I;
tx_fifo_we <= WE_I;
DAT_O <= (31 downto pcm_data_width => '0') & rx_fifo_dout;
when others => null;
end case;
end if;
end if;
end if;
end process;
end behavior;
+309
View File
@@ -0,0 +1,309 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 08:27:43 08/26/2006
-- Design Name:
-- Module Name: ac_out - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ac_in is
Port (
rst : in std_logic;
clk : in std_logic;
sync_frame : out std_logic;
sync_status : out std_logic;
slot_valid : out unsigned(0 to 12);
stat_addr : out unsigned (19 downto 0);
stat_data : out unsigned (19 downto 0);
pcm_out_addr : in unsigned (3 downto 0);
pcm_out_data : out unsigned (19 downto 0);
ac_reset : in std_logic;
ac_bit_clk : in std_logic;
ac_sdata_in : in std_logic;
ac_ssync : in std_logic
);
end ac_in;
architecture Behavioral of ac_in is
------------------------------------------------------------------
COMPONENT singleshot
GENERIC (mode : integer);
PORT(
rst : IN std_logic;
clk : IN std_logic;
input : IN std_logic;
output : OUT std_logic
);
END COMPONENT;
------------------------------------------------------------------
type sac_t is (ac_idle, ac_tag, ac_data);
subtype bitcnt_t is integer range 0 to 19;
subtype slotcnt_t is integer range 0 to 12;
subtype slot_valid_t is UNSIGNED(0 to 12);
subtype tag_t is UNSIGNED(15 downto 0);
subtype slot_t is UNSIGNED(19 downto 0);
type slot_array_t is array (natural range <>) of slot_t;
signal data_array : slot_array_t (1 to 12);
signal tag : tag_t;
signal sac, snac : sac_t;
signal bitcnt : bitcnt_t;
signal bitcnt_rst, bitcnt_en : STD_LOGIC;
signal slotcnt : slotcnt_t;
signal slotcnt_rst, slotcnt_en : STD_LOGIC;
signal rx_reg : slot_t;
signal stat_read, host_update : STD_LOGIC;
signal sync_end, slot_end, last_slot, start_of_frame : STD_LOGIC;
------------------------------------------------------------------
function GetSlotValid(data : tag_t) return slot_valid_t is
variable res : slot_valid_t := (others => '0');
begin
res := (others => '0');
for i in slot_valid_t'range loop
res(i) := data(data'left-i);
end loop;
return res;
end GetSlotValid;
------------------------------------------------------------------
begin
-------------------------------------------------------------
-- proc_status_flags
-------------------------------------------------------------
proc_status_flags:
process (rst, clk, host_update, tag, data_array)
begin
if rising_edge(clk) then
sync_status <= '0';
if rst = '1' then
slot_valid <= (others => '0');
stat_addr <= (others => '0');
stat_data <= (others => '0');
elsif host_update = '1' then
sync_status <= '1';
slot_valid <= GetSlotValid(tag);
stat_addr <= data_array(1);
stat_data <= data_array(2);
end if;
end if;
end process;
-------------------------------------------------------------
-- proc_pcm_data
-------------------------------------------------------------
proc_pcm_data:
process (clk, pcm_out_addr, data_array)
variable slot_id : integer range 0 to 12;
begin
pcm_out_data <= (others => '-');
slot_id := to_integer(pcm_out_addr);
if (slot_id > 2) then
pcm_out_data <= data_array(slot_id);
end if;
end process;
-------------------------------------------------------------
-- proc_read_data
-------------------------------------------------------------
proc_read_data :
process (ac_reset, ac_bit_clk, slot_end, slotcnt)
begin
if ac_reset = '1' then
stat_read <= '0';
elsif rising_edge(ac_bit_clk) then
stat_read <= '0';
if slot_end = '1' and slotcnt /= 0 then
data_array(slotcnt) <= rx_reg;
if slotcnt = 2 then
stat_read <= '1';
end if;
end if;
end if;
end process;
-------------------------------------------------------------
-- proc_read_stat
-------------------------------------------------------------
proc_read_tag :
process (ac_reset, ac_bit_clk, sync_end)
begin
if ac_reset = '1' then
tag <= (others => '0');
elsif rising_edge(ac_bit_clk) then
if sync_end = '1' then
tag <= rx_reg(15 downto 0);
end if;
end if;
end process;
-------------------------------------------------------------
-- proc_slot_count
-------------------------------------------------------------
proc_slot_count:
process (slotcnt_rst, ac_bit_clk, slotcnt_en, slotcnt)
begin
if rising_edge(ac_bit_clk) then
if slotcnt_rst = '1' then
slotcnt <= slotcnt_t'low;
elsif slotcnt_en = '1' then
if slotcnt /= slotcnt_t'high then
slotcnt <= slotcnt + 1;
else
slotcnt <= slotcnt_t'low;
end if;
end if;
end if;
end process;
-------------------------------------------------------------
-- proc_bit_count
-------------------------------------------------------------
proc_bit_count:
process (bitcnt_rst, ac_bit_clk, bitcnt_en, bitcnt)
begin
if rising_edge(ac_bit_clk) then
if bitcnt_rst = '1' then
bitcnt <= bitcnt_t'low;
elsif bitcnt_en = '1' then
if bitcnt /= bitcnt_t'high then
bitcnt <= bitcnt + 1;
else
bitcnt <= bitcnt_t'low;
end if;
end if;
end if;
end process;
------------------------------------------------------------------
proc_ac_fsm:
process (bitcnt, slotcnt, sac, ac_ssync)
begin
snac <= sac;
bitcnt_rst <= '0';
bitcnt_en <= '1';
slotcnt_rst <= '0';
slotcnt_en <= '0';
slot_end <= '0';
sync_end <= '0';
last_slot <= '0';
start_of_frame <= '0';
if bitcnt = 19 then
slot_end <= '1';
end if;
if slotcnt = 12 and bitcnt = 19 then
last_slot <= '1';
end if;
case sac is
when ac_idle =>
bitcnt_rst <= '1';
slotcnt_rst <= '1';
if (ac_ssync = '1') then
snac <= ac_tag;
end if;
when ac_tag =>
if (bitcnt = 0) then
start_of_frame <= '1';
elsif (bitcnt = 15) then
slotcnt_en <= '1';
bitcnt_rst <= '1';
sync_end <= '1';
if (ac_ssync = '0') then
snac <= ac_data;
else
snac <= ac_idle;
end if;
end if;
when ac_data =>
if bitcnt = 19 then
slotcnt_en <= '1';
if slotcnt = 12 then
slotcnt_rst <= '1';
snac <= ac_tag;
end if;
end if;
when others => null;
end case;
end process;
proc_ac_fsm_next:
process (ac_reset, ac_bit_clk, snac)
begin
if ac_reset = '1' then
sac <= ac_idle;
elsif rising_edge(ac_bit_clk) then
sac <= snac;
end if;
end process;
-------------------------------------------------------------
-- Receive Shift Register
-------------------------------------------------------------
process (ac_reset, ac_bit_clk, ac_sdata_in)
begin
if ac_reset = '1' then
rx_reg <= (others => '0');
elsif falling_edge(ac_bit_clk) then
rx_reg <= rx_reg(rx_reg'left-1 downto 0) & ac_sdata_in;
end if;
end process;
------------------------------------------------------------------
singleshot_inst1: singleshot
GENERIC MAP (
mode => 0)
PORT MAP(
rst => rst,
clk => clk,
input => stat_read,
output => host_update
);
singleshot_inst2: singleshot
GENERIC MAP (
mode => 1)
PORT MAP(
rst => rst,
clk => clk,
input => start_of_frame,
output => sync_frame
);
-------------------------------------------------------------
end Behavioral;
+189
View File
@@ -0,0 +1,189 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 18:29:55 08/26/2006
-- Design Name:
-- Module Name: ac_io - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ac_io is
Port
(
rst : in std_logic;
clk : in std_logic;
ready : out std_logic;
sync_strobe : out unsigned(0 to 2);
slot_valid : out unsigned(0 to 12);
stat_addr : out unsigned (19 downto 0);
stat_data : out unsigned (19 downto 0);
rx_pcm_addr : in unsigned (3 downto 0);
rx_pcm_data : out unsigned (19 downto 0);
cmd_addr : in unsigned(19 downto 0);
cmd_data : in unsigned(19 downto 0);
cmd_we : in std_logic;
tx_pcm_addr : in unsigned(3 downto 0);
tx_pcm_data : in unsigned(19 downto 0);
tx_pcm_we : in std_logic;
ac_sdata_in : in std_logic;
ac_bit_clk : in std_logic;
ac_reset_n : out std_logic;
ac_sdata_out : out std_logic;
ac_ssync : out std_logic
);
end ac_io;
architecture Behavioral of ac_io is
COMPONENT ac_in
Port
(
rst : in std_logic;
clk : in std_logic;
sync_frame : out std_logic;
sync_status : out std_logic;
slot_valid : out unsigned(0 to 12);
stat_addr : out unsigned (19 downto 0);
stat_data : out unsigned (19 downto 0);
pcm_out_addr : in unsigned (3 downto 0);
pcm_out_data : out unsigned (19 downto 0);
ac_reset : in std_logic;
ac_bit_clk : in std_logic;
ac_sdata_in : in std_logic;
ac_ssync : in std_logic
);
END COMPONENT;
COMPONENT ac_out
PORT
(
rst : in std_logic;
clk : in std_logic;
sync_tx : out std_logic;
cmd_addr : in unsigned(19 downto 0);
cmd_data : in unsigned(19 downto 0);
cmd_we : in std_logic;
pcm_in_addr : in unsigned(3 downto 0);
pcm_in_data : in unsigned(19 downto 0);
pcm_in_we : in std_logic;
ac_bit_clk : in std_logic;
ac_reset : in std_logic;
ac_sdata_out : out std_logic;
ac_ssync : out std_logic
);
END COMPONENT;
SIGNAL ac_reset : std_logic;
SIGNAL ssync_rx : std_logic;
SIGNAL ssync_tx : std_logic;
SIGNAL sync_frame : std_logic;
SIGNAL sync_status : std_logic;
SIGNAL sync_tx : std_logic;
begin
inst_ac_in: ac_in
PORT MAP
(
rst => rst,
clk => clk,
sync_frame => sync_frame,
sync_status => sync_status,
slot_valid => slot_valid,
stat_addr => stat_addr,
stat_data => stat_data,
pcm_out_addr => rx_pcm_addr,
pcm_out_data => rx_pcm_data,
ac_reset => ac_reset,
ac_bit_clk => ac_bit_clk,
ac_sdata_in => ac_sdata_in,
ac_ssync => ssync_rx
);
inst_ac_out: ac_out
PORT MAP
(
rst => rst,
clk => clk,
sync_tx => sync_tx,
cmd_addr => cmd_addr,
cmd_data => cmd_data,
cmd_we => cmd_we,
pcm_in_addr => tx_pcm_addr,
pcm_in_data => tx_pcm_data,
pcm_in_we => tx_pcm_we,
ac_reset => ac_reset,
ac_bit_clk => ac_bit_clk,
ac_sdata_out => ac_sdata_out,
ac_ssync => ssync_tx
);
------------------------------------------------------------------
ready <= not ac_reset;
ac_ssync <= ssync_tx;
ssync_rx <= ssync_tx;
sync_strobe <= sync_frame & sync_status & sync_tx;
------------------------------------------------------------------
proc_reset_gen:
process (rst, clk, ac_bit_clk)
type rstate_t is (s0, s1);
variable rstate, rstaten : rstate_t;
subtype cnt_t is integer range 0 to 999;
variable cnt : cnt_t;
begin
if rising_edge(clk) then
if rst = '1' then
rstate := s0;
cnt := cnt_t'high;
ac_reset <= '1';
ac_reset_n <= '0';
else
rstaten := rstate;
case rstate is
when s0 =>
if cnt /= 0 then
cnt := cnt - 1;
else
ac_reset_n <= '1';
if ac_bit_clk = '1' then
rstaten := s1;
cnt := cnt_t'high;
end if;
end if;
when s1 =>
if cnt /= 0 then
cnt := cnt - 1;
else
ac_reset <= '0';
end if;
end case;
rstate := rstaten;
end if;
end if;
end process;
------------------------------------------------------------------
end Behavioral;
+276
View File
@@ -0,0 +1,276 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15:41:12 06/05/2007
-- Design Name:
-- Module Name: ac_out - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ac_out is
Port (
rst : in std_logic;
clk : in std_logic;
sync_tx : out std_logic;
cmd_addr : in unsigned (19 downto 0);
cmd_data : in unsigned (19 downto 0);
cmd_we : in std_logic;
pcm_in_addr : in unsigned (3 downto 0);
pcm_in_data : in unsigned (19 downto 0);
pcm_in_we : in std_logic;
ac_reset : in std_logic;
ac_bit_clk : in std_logic;
ac_sdata_out : out std_logic;
ac_ssync : out std_logic
);
end ac_out;
architecture Behavioral of ac_out is
------------------------------------------------------------------
COMPONENT singleshot
GENERIC (mode : integer);
PORT(
rst : IN std_logic;
clk : IN std_logic;
input : IN std_logic;
output : OUT std_logic
);
END COMPONENT;
------------------------------------------------------------------
subtype tag_t is UNSIGNED(15 downto 0);
subtype slot_valid_t is UNSIGNED(1 to 12);
signal slot_valid : slot_valid_t;
subtype slot_t is UNSIGNED(19 downto 0);
type slot_array_t is array (natural range <>) of slot_t;
signal data_array : slot_array_t (1 to 12);
signal tx_reg : UNSIGNED(19 downto 0);
signal last_slot, ssync : STD_LOGIC;
type sac_t is (ac_idle, ac_tag, ac_data);
signal sac, snac : sac_t;
subtype bitcnt_t is integer range 0 to 19;
subtype slotcnt_t is integer range 0 to 12;
signal bitcnt : bitcnt_t;
signal bitcnt_rst, bitcnt_en : STD_LOGIC;
signal slotcnt : slotcnt_t;
signal slotcnt_rst, slotcnt_en : STD_LOGIC;
signal slot_start : STD_LOGIC;
------------------------------------------------------------------
function CreateTag(slot_valid : slot_valid_t) return tag_t is
variable tag : tag_t := (others => '0');
begin
tag := (others => '0');
for i in slot_valid_t'range loop
tag(15-i) := slot_valid(i);
if slot_valid(i) = '1' then
tag(15) := '1';
end if;
end loop;
tag(0) := '0'; -- ID0
tag(1) := '0'; -- ID1
tag(2) := '0'; -- Reserved
-- tag(15) := '1'; -- Frame is valid
return tag;
end CreateTag;
begin
------------------------------------------------------------------
proc_slot_reg:
process (clk, cmd_addr, cmd_data, cmd_we, pcm_in_data, pcm_in_we, pcm_in_addr, last_slot)
variable slot_id : integer range 0 to 12;
begin
slot_id := to_integer(pcm_in_addr);
if rising_edge(clk) then
if rst = '1' then
for i in data_array'range(1) loop
data_array(i) <= (others => '0');
end loop;
slot_valid <= (others => '0');
elsif last_slot = '1' then
slot_valid <= (others => '0');
else
if cmd_we = '1' then
slot_valid(1) <= '1';
slot_valid(2) <= '1';
data_array(1) <= cmd_addr;
data_array(2) <= cmd_data;
end if;
if pcm_in_we = '1' then
if (slot_id > 2) then
data_array(slot_id) <= pcm_in_data;
slot_valid(slot_id) <= '1';
end if;
end if;
end if;
end if;
end process;
-------------------------------------------------------------
-- proc_slot_count
-------------------------------------------------------------
proc_slot_count:
process (slotcnt_rst, ac_bit_clk, slotcnt_en, slotcnt)
begin
if rising_edge(ac_bit_clk) then
if slotcnt_rst = '1' then
slotcnt <= slotcnt_t'low;
elsif slotcnt_en = '1' then
if slotcnt /= slotcnt_t'high then
slotcnt <= slotcnt + 1;
else
slotcnt <= slotcnt_t'low;
end if;
end if;
end if;
end process;
------------------------------------------------------------------
-- proc_bit_count
------------------------------------------------------------------
proc_bit_count:
process (bitcnt_rst, ac_bit_clk, bitcnt_en, bitcnt)
begin
if rising_edge(ac_bit_clk) then
if bitcnt_rst = '1' then
bitcnt <= bitcnt_t'low;
elsif bitcnt_en = '1' then
if bitcnt /= bitcnt_t'high then
bitcnt <= bitcnt + 1;
else
bitcnt <= bitcnt_t'low;
end if;
end if;
end if;
end process;
------------------------------------------------------------------
proc_ac_fsm:
process (bitcnt, slotcnt, sac)
begin
snac <= sac;
bitcnt_rst <= '0';
bitcnt_en <= '1';
slotcnt_rst <= '0';
slotcnt_en <= '0';
slot_start <= '0';
ssync <= '0';
if bitcnt = 0 then
slot_start <= '1';
end if;
case sac is
when ac_idle =>
bitcnt_rst <= '1';
slotcnt_rst <= '1';
snac <= ac_tag;
when ac_tag =>
ssync <= '1';
if (bitcnt = 15) then
slotcnt_en <= '1';
bitcnt_rst <= '1';
snac <= ac_data;
end if;
when ac_data =>
if bitcnt = 19 then
slotcnt_en <= '1';
if slotcnt = 12 then
slotcnt_rst <= '1';
snac <= ac_tag;
end if;
end if;
when others => null;
end case;
end process;
proc_ac_fsm_next:
process (ac_reset, ac_bit_clk, snac)
begin
if ac_reset = '1' then
sac <= ac_idle;
elsif rising_edge(ac_bit_clk) then
sac <= snac;
end if;
end process;
------------------------------------------------------------------
proc_tx_shift_reg:
process (ac_reset, ac_bit_clk, tx_reg, ssync, slot_valid, data_array)
begin
if ac_reset = '1' then
tx_reg <= (others => '0');
elsif rising_edge(ac_bit_clk) then
last_slot <= '0';
if slot_start = '1' then
if ssync = '1' then
tx_reg <= CreateTag(slot_valid) & "0000";
else
if slotcnt /= 0 then
tx_reg <= data_array(slotcnt);
if slotcnt = 12 then
last_slot <= '1';
end if;
end if;
end if;
else
tx_reg <= tx_reg(tx_reg'left-1 downto 0) & '0';
end if;
end if;
end process;
------------------------------------------------------------------
proc_ac_sync_out:
process (ac_reset, ac_bit_clk, ssync, tx_reg)
begin
if ac_reset = '1' then
ac_ssync <= '0';
ac_sdata_out <= '0';
elsif rising_edge(ac_bit_clk) then
ac_ssync <= ssync;
ac_sdata_out <= tx_reg(tx_reg'left);
end if;
end process;
------------------------------------------------------------------
singleshot_inst1: singleshot
GENERIC MAP (
mode => 0)
PORT MAP(
rst => rst,
clk => clk,
input => last_slot,
output => sync_tx
);