From 5091040c1df38236b18e953709c29896c88a2bf6 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sat, 1 Nov 2008 21:48:26 +0000 Subject: [PATCH] - Intital revision git-svn-id: http://moon:8086/svn/vhdl/trunk@133 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/ac97_ctrl/sim/tb_ac97_wb.fdo | 20 ++ lib/ac97_ctrl/sim/tb_ac97_wb.wdo | 77 +++++++ lib/ac97_ctrl/sim/tb_ac_in.fdo | 14 ++ lib/ac97_ctrl/sim/tb_ac_in.wdo | 43 ++++ lib/ac97_ctrl/sim/tb_ac_io.fdo | 15 ++ lib/ac97_ctrl/sim/tb_ac_io.wdo | 51 +++++ lib/ac97_ctrl/sim/tb_ac_out.fdo | 13 ++ lib/ac97_ctrl/sim/tb_ac_out.wdo | 41 ++++ lib/ac97_ctrl/src/core/ac97_wb.vhd | 351 +++++++++++++++++++++++++++++ lib/ac97_ctrl/src/core/ac_in.vhd | 309 +++++++++++++++++++++++++ lib/ac97_ctrl/src/core/ac_io.vhd | 189 ++++++++++++++++ lib/ac97_ctrl/src/core/ac_out.vhd | 276 +++++++++++++++++++++++ lib/ac97_ctrl/src/tb_ac97_wb.vhd | 152 +++++++++++++ lib/ac97_ctrl/src/tb_ac_in.vhd | 203 +++++++++++++++++ lib/ac97_ctrl/src/tb_ac_io.vhd | 186 +++++++++++++++ lib/ac97_ctrl/src/tb_ac_out.vhd | 149 ++++++++++++ 16 files changed, 2089 insertions(+) create mode 100644 lib/ac97_ctrl/sim/tb_ac97_wb.fdo create mode 100644 lib/ac97_ctrl/sim/tb_ac97_wb.wdo create mode 100644 lib/ac97_ctrl/sim/tb_ac_in.fdo create mode 100644 lib/ac97_ctrl/sim/tb_ac_in.wdo create mode 100644 lib/ac97_ctrl/sim/tb_ac_io.fdo create mode 100644 lib/ac97_ctrl/sim/tb_ac_io.wdo create mode 100644 lib/ac97_ctrl/sim/tb_ac_out.fdo create mode 100644 lib/ac97_ctrl/sim/tb_ac_out.wdo create mode 100644 lib/ac97_ctrl/src/core/ac97_wb.vhd create mode 100644 lib/ac97_ctrl/src/core/ac_in.vhd create mode 100644 lib/ac97_ctrl/src/core/ac_io.vhd create mode 100644 lib/ac97_ctrl/src/core/ac_out.vhd create mode 100644 lib/ac97_ctrl/src/tb_ac97_wb.vhd create mode 100644 lib/ac97_ctrl/src/tb_ac_in.vhd create mode 100644 lib/ac97_ctrl/src/tb_ac_io.vhd create mode 100644 lib/ac97_ctrl/src/tb_ac_out.vhd diff --git a/lib/ac97_ctrl/sim/tb_ac97_wb.fdo b/lib/ac97_ctrl/sim/tb_ac97_wb.fdo new file mode 100644 index 0000000..cb5a3e7 --- /dev/null +++ b/lib/ac97_ctrl/sim/tb_ac97_wb.fdo @@ -0,0 +1,20 @@ +## NOTE: Do not edit this file. +## Autogenerated by ProjNav (creatfdo.tcl) on Tue Jun 05 17:37:16 Westeuropäische Normalzeit 2007 +## +vlib work +vcom -explicit -93 "../../FIFO/src/fifo_ctrl_pkg.vhd" +vcom -explicit -93 "../../FIFO/src/sync_fifo_ctrl.vhd" +vcom -explicit -93 "../../misc/dpram_1w1r_dist.vhd" +vcom -explicit -93 "../../FIFO/src/fifo_sync_dist.vhd" +vcom -explicit -93 "../../misc/singleshot.vhd" +vcom -explicit -93 "../src/core/ac_out.vhd" +vcom -explicit -93 "../src/core/ac_in.vhd" +vcom -explicit -93 "../src/core/ac_io.vhd" +vcom -explicit -93 "../src/core/ac97_wb.vhd" +vcom -explicit -93 "../src/tb_ac97_wb.vhd" +vsim -t 1ps -lib work tb_ac97_wb +do {tb_ac97_wb.wdo} +view wave +view structure +view signals +run 700us diff --git a/lib/ac97_ctrl/sim/tb_ac97_wb.wdo b/lib/ac97_ctrl/sim/tb_ac97_wb.wdo new file mode 100644 index 0000000..f7e1885 --- /dev/null +++ b/lib/ac97_ctrl/sim/tb_ac97_wb.wdo @@ -0,0 +1,77 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -format Logic /tb_ac97_wb/clk_o +add wave -noupdate -format Logic /tb_ac97_wb/rst_o +add wave -noupdate -format Logic /tb_ac97_wb/int_i +add wave -noupdate -format Logic /tb_ac97_wb/cyc_o +add wave -noupdate -format Logic /tb_ac97_wb/stb_o +add wave -noupdate -format Logic /tb_ac97_wb/we_o +add wave -noupdate -format Logic /tb_ac97_wb/ack_i +add wave -noupdate -format Logic /tb_ac97_wb/mrdy_o +add wave -noupdate -format Logic /tb_ac97_wb/srdy_i +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/addr_o +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/dat_i +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/dat_o +add wave -noupdate -format Logic /tb_ac97_wb/dout_rst +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/dout_reg +add wave -noupdate -format Literal /tb_ac97_wb/dout_cnt +add wave -noupdate -format Logic /tb_ac97_wb/ac97_bit_clk +add wave -noupdate -format Logic /tb_ac97_wb/ac97_reset_n +add wave -noupdate -format Logic /tb_ac97_wb/ac97_sdata_out +add wave -noupdate -format Logic /tb_ac97_wb/ac97_ssync +add wave -noupdate -format Logic /tb_ac97_wb/ac97_sdata_in +add wave -noupdate -divider UUT +add wave -noupdate -format Logic /tb_ac97_wb/uut/cmd_reg_we +add wave -noupdate -format Logic /tb_ac97_wb/uut/cmd_pending +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/uut/ac_cmd_data +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/uut/ac_cmd_addr +add wave -noupdate -format Logic /tb_ac97_wb/uut/ac_cmd_we +add wave -noupdate -format Logic /tb_ac97_wb/uut/ac_tx_pcm_we +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/uut/stat_reg +add wave -noupdate -format Logic /tb_ac97_wb/uut/stat_reg_re +add wave -noupdate -format Logic /tb_ac97_wb/uut/stat_pending +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/uut/ac_stat_data +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/uut/ac_stat_addr +add wave -noupdate -format Literal /tb_ac97_wb/uut/ac_tx_pcm_addr +add wave -noupdate -format Literal /tb_ac97_wb/uut/ac_rx_pcm_addr +add wave -noupdate -format Literal /tb_ac97_wb/uut/ac_sync_strobe +add wave -noupdate -format Literal /tb_ac97_wb/uut/ac_slot_valid +add wave -noupdate -format Logic /tb_ac97_wb/uut/ac_ready +add wave -noupdate -format Logic /tb_ac97_wb/uut/tx_data_start +add wave -noupdate -format Logic /tb_ac97_wb/clk_o +add wave -noupdate -format Logic /tb_ac97_wb/uut/sync_status +add wave -noupdate -format Logic /tb_ac97_wb/uut/sync_frame +add wave -noupdate -format Logic /tb_ac97_wb/uut/rx_frame_valid +add wave -noupdate -format Logic /tb_ac97_wb/uut/sync_tx +add wave -noupdate -format Literal /tb_ac97_wb/uut/request +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/uut/tx_fifo_din +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/uut/tx_fifo_dout +add wave -noupdate -format Logic /tb_ac97_wb/uut/tx_fifo_re +add wave -noupdate -format Logic /tb_ac97_wb/uut/tx_fifo_we +add wave -noupdate -format Logic /tb_ac97_wb/uut/tx_fifo_full +add wave -noupdate -format Logic /tb_ac97_wb/uut/tx_fifo_empty +add wave -noupdate -format Logic /tb_ac97_wb/uut/rx_data_start +add wave -noupdate -format Logic /tb_ac97_wb/clk_o +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/uut/rx_fifo_din +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/uut/rx_fifo_dout +add wave -noupdate -format Logic /tb_ac97_wb/uut/rx_fifo_re +add wave -noupdate -format Logic /tb_ac97_wb/uut/rx_fifo_we +add wave -noupdate -format Logic /tb_ac97_wb/uut/rx_fifo_full +add wave -noupdate -format Logic /tb_ac97_wb/uut/rx_fifo_empty +add wave -noupdate -format Literal -radix hexadecimal /tb_ac97_wb/uut/ac97_stat +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 4} {200000401 ps} 0} {{Cursor 2} {699514236 ps} 0} {{Cursor 4} {4999959266 ps} 0} +configure wave -namecolwidth 173 +configure wave -valuecolwidth 100 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +update +WaveRestoreZoom {699260742 ps} {700038909 ps} diff --git a/lib/ac97_ctrl/sim/tb_ac_in.fdo b/lib/ac97_ctrl/sim/tb_ac_in.fdo new file mode 100644 index 0000000..fd7fb1f --- /dev/null +++ b/lib/ac97_ctrl/sim/tb_ac_in.fdo @@ -0,0 +1,14 @@ +## NOTE: Do not edit this file. +## Autogenerated by ProjNav (creatfdo.tcl) on Tue Jun 05 17:37:16 Westeuropäische Normalzeit 2007 +## +vlib work +vcom -explicit -93 "../../../lib/src/misc/singleshot.vhd" +vcom -explicit -93 "../src/core/ac_out.vhd" +vcom -explicit -93 "../src/core/ac_in.vhd" +vcom -explicit -93 "../src/tb_ac_in.vhd" +vsim -t 1ps -lib work tb_ac_in +do {tb_ac_in.wdo} +view wave +view structure +view signals +run 700us diff --git a/lib/ac97_ctrl/sim/tb_ac_in.wdo b/lib/ac97_ctrl/sim/tb_ac_in.wdo new file mode 100644 index 0000000..a7d0e35 --- /dev/null +++ b/lib/ac97_ctrl/sim/tb_ac_in.wdo @@ -0,0 +1,43 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -format Logic /tb_ac_in/uut/rst +add wave -noupdate -format Logic /tb_ac_in/uut/clk +add wave -noupdate -format Logic /tb_ac_in/uut/sync_frame +add wave -noupdate -format Logic /tb_ac_in/uut/sync_status +add wave -noupdate -divider {AC97 lines} +add wave -noupdate -format Logic /tb_ac_in/uut/ac_reset +add wave -noupdate -format Logic /tb_ac_in/uut/ac_bit_clk +add wave -noupdate -format Logic /tb_ac_in/uut/ac_sdata_in +add wave -noupdate -format Logic /tb_ac_in/uut/ac_ssync +add wave -noupdate -divider Debug +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_in/uut/stat_addr +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_in/uut/stat_data +add wave -noupdate -format Literal /tb_ac_in/uut/pcm_out_addr +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_in/uut/pcm_out_data +add wave -noupdate -format Literal -radix hexadecimal -expand /tb_ac_in/uut/data_array +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_in/uut/tag +add wave -noupdate -format Literal /tb_ac_in/uut/sac +add wave -noupdate -format Literal /tb_ac_in/uut/bitcnt +add wave -noupdate -format Literal /tb_ac_in/uut/slotcnt +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_in/uut/rx_reg +add wave -noupdate -format Logic /tb_ac_in/uut/stat_read +add wave -noupdate -format Logic /tb_ac_in/uut/host_update +add wave -noupdate -format Logic /tb_ac_in/uut/slot_end +add wave -noupdate -format Logic /tb_ac_in/uut/sync_end +add wave -noupdate -format Logic /tb_ac_in/uut/last_slot +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {53431686 ps} 0} {{Cursor 2} {44308511 ps} 0} {{Cursor 4} {677821715 ps} 0} +configure wave -namecolwidth 173 +configure wave -valuecolwidth 100 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +update +WaveRestoreZoom {52190046 ps} {56168939 ps} diff --git a/lib/ac97_ctrl/sim/tb_ac_io.fdo b/lib/ac97_ctrl/sim/tb_ac_io.fdo new file mode 100644 index 0000000..4b0180f --- /dev/null +++ b/lib/ac97_ctrl/sim/tb_ac_io.fdo @@ -0,0 +1,15 @@ +## NOTE: Do not edit this file. +## Autogenerated by ProjNav (creatfdo.tcl) on Tue Jun 05 17:37:16 Westeuropäische Normalzeit 2007 +## +vlib work +vcom -explicit -93 "../../../lib/misc/singleshot.vhd" +vcom -explicit -93 "../src/core/ac_out.vhd" +vcom -explicit -93 "../src/core/ac_in.vhd" +vcom -explicit -93 "../src/core/ac_io.vhd" +vcom -explicit -93 "../src/tb_ac_io.vhd" +vsim -t 1ps -lib work tb_ac_io +do {tb_ac_io.wdo} +view wave +view structure +view signals +run 700us diff --git a/lib/ac97_ctrl/sim/tb_ac_io.wdo b/lib/ac97_ctrl/sim/tb_ac_io.wdo new file mode 100644 index 0000000..b445bdb --- /dev/null +++ b/lib/ac97_ctrl/sim/tb_ac_io.wdo @@ -0,0 +1,51 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -format Logic /tb_ac_io/uut/rst +add wave -noupdate -format Logic /tb_ac_io/uut/clk +add wave -noupdate -format Logic /tb_ac_io/uut/ready +add wave -noupdate -format Literal /tb_ac_io/uut/slot_valid +add wave -noupdate -format Logic /tb_ac_io/uut/sync_strobe +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_io/uut/stat_addr +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_io/uut/stat_data +add wave -noupdate -format Literal /tb_ac_io/uut/rx_pcm_addr +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_io/uut/rx_pcm_data +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_io/uut/cmd_addr +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_io/uut/cmd_data +add wave -noupdate -format Logic /tb_ac_io/uut/cmd_we +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_io/uut/tx_pcm_addr +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_io/uut/tx_pcm_data +add wave -noupdate -format Logic /tb_ac_io/uut/tx_pcm_we +add wave -noupdate -divider {AC97 lines} +add wave -noupdate -format Logic /tb_ac_io/uut/ac_sdata_in +add wave -noupdate -format Logic /tb_ac_io/uut/ac_bit_clk +add wave -noupdate -format Logic /tb_ac_io/uut/ac_reset_n +add wave -noupdate -format Logic /tb_ac_io/uut/ac_sdata_out +add wave -noupdate -format Logic /tb_ac_io/uut/ac_ssync +add wave -noupdate -divider Debug +add wave -noupdate -format Logic /tb_ac_io/uut/inst_ac_in/stat_read +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_io/uut/inst_ac_in/rx_reg +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_io/uut/inst_ac_out/tx_reg +add wave -noupdate -format Literal /tb_ac_io/uut/inst_ac_in/bitcnt +add wave -noupdate -format Literal /tb_ac_io/uut/inst_ac_in/sac +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_io/uut/inst_ac_in/tag +add wave -noupdate -format Literal /tb_ac_io/uut/inst_ac_in/data_array +add wave -noupdate -format Literal /tb_ac_io/uut/inst_ac_out/bitcnt +add wave -noupdate -format Literal /tb_ac_io/uut/inst_ac_out/slotcnt +add wave -noupdate -format Logic /tb_ac_io/uut/inst_ac_out/ssync +add wave -noupdate -format Literal /tb_ac_io/uut/inst_ac_out/slot_valid +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 4} {0 ps} 0} {{Cursor 2} {292930000 ps} 0} {{Cursor 4} {4999959266 ps} 0} +configure wave -namecolwidth 173 +configure wave -valuecolwidth 100 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +update +WaveRestoreZoom {0 ps} {735 us} diff --git a/lib/ac97_ctrl/sim/tb_ac_out.fdo b/lib/ac97_ctrl/sim/tb_ac_out.fdo new file mode 100644 index 0000000..ac9d3c4 --- /dev/null +++ b/lib/ac97_ctrl/sim/tb_ac_out.fdo @@ -0,0 +1,13 @@ +## NOTE: Do not edit this file. +## Autogenerated by ProjNav (creatfdo.tcl) on Tue Jun 05 17:37:16 Westeuropäische Normalzeit 2007 +## +vlib work +vcom -explicit -93 "../../../lib/src/misc/singleshot.vhd" +vcom -explicit -93 "../src/core/ac_out.vhd" +vcom -explicit -93 "../src/tb_ac_out.vhd" +vsim -t 1ps -lib work tb_ac_out +do {tb_ac_out.wdo} +view wave +view structure +view signals +run 600us diff --git a/lib/ac97_ctrl/sim/tb_ac_out.wdo b/lib/ac97_ctrl/sim/tb_ac_out.wdo new file mode 100644 index 0000000..b9d9a25 --- /dev/null +++ b/lib/ac97_ctrl/sim/tb_ac_out.wdo @@ -0,0 +1,41 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -format Logic /tb_ac_out/rst +add wave -noupdate -format Logic /tb_ac_out/clk +add wave -noupdate -format Logic /tb_ac_out/ce +add wave -noupdate -divider {Host hand shake} +add wave -noupdate -format Logic /tb_ac_out/sync_tx +add wave -noupdate -divider {Command I/F} +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_out/cmd_addr +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_out/cmd_data +add wave -noupdate -format Logic /tb_ac_out/uut/cmd_we +add wave -noupdate -divider {PCM I/F} +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_out/pcm_in_addr +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_out/pcm_in_data +add wave -noupdate -format Logic /tb_ac_out/pcm_in_we +add wave -noupdate -divider {AC97 I/F} +add wave -noupdate -format Logic /tb_ac_out/ac_bit_clk +add wave -noupdate -format Logic /tb_ac_out/ac_reset +add wave -noupdate -format Logic /tb_ac_out/ac_sdata_out +add wave -noupdate -format Logic /tb_ac_out/ac_ssync +add wave -noupdate -divider Debug +add wave -noupdate -format Literal -radix hexadecimal /tb_ac_out/uut/tx_reg +add wave -noupdate -format Literal /tb_ac_out/uut/sac +add wave -noupdate -format Literal /tb_ac_out/uut/bitcnt +add wave -noupdate -format Literal /tb_ac_out/uut/slotcnt +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {544839100 ps} 0} +configure wave -namecolwidth 150 +configure wave -valuecolwidth 100 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +update +WaveRestoreZoom {532851785 ps} {556826415 ps} diff --git a/lib/ac97_ctrl/src/core/ac97_wb.vhd b/lib/ac97_ctrl/src/core/ac97_wb.vhd new file mode 100644 index 0000000..ac031fa --- /dev/null +++ b/lib/ac97_ctrl/src/core/ac97_wb.vhd @@ -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; diff --git a/lib/ac97_ctrl/src/core/ac_in.vhd b/lib/ac97_ctrl/src/core/ac_in.vhd new file mode 100644 index 0000000..a072a9b --- /dev/null +++ b/lib/ac97_ctrl/src/core/ac_in.vhd @@ -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; + diff --git a/lib/ac97_ctrl/src/core/ac_io.vhd b/lib/ac97_ctrl/src/core/ac_io.vhd new file mode 100644 index 0000000..211a5ef --- /dev/null +++ b/lib/ac97_ctrl/src/core/ac_io.vhd @@ -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; + diff --git a/lib/ac97_ctrl/src/core/ac_out.vhd b/lib/ac97_ctrl/src/core/ac_out.vhd new file mode 100644 index 0000000..a770495 --- /dev/null +++ b/lib/ac97_ctrl/src/core/ac_out.vhd @@ -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 +); + +end Behavioral; diff --git a/lib/ac97_ctrl/src/tb_ac97_wb.vhd b/lib/ac97_ctrl/src/tb_ac97_wb.vhd new file mode 100644 index 0000000..7ab47a4 --- /dev/null +++ b/lib/ac97_ctrl/src/tb_ac97_wb.vhd @@ -0,0 +1,152 @@ + +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 17:33:47 06/05/2007 +-- Design Name: eval_ac +-- Module Name: E:/work/VHDL/eval_ac/tb_eval_ac.vhd +-- Project Name: ac_out +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: ac_out +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY tb_ac97_wb IS +END tb_ac97_wb; + +ARCHITECTURE behavior OF tb_ac97_wb IS + + constant SYS_CLK_PERIOD : time := 10 ns; + CONSTANT BIT_CLK_PERIOD : time := 100 ns; +-- constant BIT_CLK_PERIOD : time := 81.38 ns; + + signal CLK_O : std_logic := '1'; + signal RST_O : std_logic := '1'; + signal CYC_O : std_logic := '0'; + signal STB_O : std_logic := '0'; + signal WE_O : std_logic := '0'; + signal ACK_I : std_logic; + signal MRDY_O : std_logic := '1'; + signal SRDY_I : std_logic; + signal INT_I : std_logic; + signal ADDR_O : unsigned(31 downto 0) := (others => '-'); + signal DAT_I : unsigned(31 downto 0); + signal DAT_O : unsigned(31 downto 0) := (others => '-'); + + signal dout_rst : std_logic := '0'; + signal dout_reg : unsigned(31 downto 0); + signal dout_cnt : natural range 0 to 255; + + SIGNAL ac97_bit_clk : std_logic := '0'; + SIGNAL ac97_reset_n : std_logic; + SIGNAL ac97_sdata_out : std_logic; + SIGNAL ac97_ssync : std_logic; + SIGNAL ac97_sdata_in : std_logic; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) +uut : entity work.ac97_wb + GENERIC MAP + ( + fifo_depth => 4 + ) + PORT MAP + ( + -- J-Bus domain + CLK_I => CLK_O, + RST_I => RST_O, + CYC_I => CYC_O, + STB_I => STB_O, + WE_I => WE_O, + ACK_O => ACK_I, + SRDY_O => SRDY_I, + MRDY_I => MRDY_O, + ADDR_I => ADDR_O, + DAT_I => DAT_O, + DAT_O => DAT_I, + INT_O => INT_I, + + -- AC97 domain + ac97_sdata_in => ac97_sdata_in, + ac97_bit_clk => ac97_bit_clk, + ac97_reset_n => ac97_reset_n, + ac97_sdata_out => ac97_sdata_out, + ac97_ssync => ac97_ssync + ); + + + ac97_sdata_in <= ac97_sdata_out; + +CLK_GEN: process + begin + wait for SYS_CLK_PERIOD/2; + CLK_O <= not CLK_O; + end process; + + bit_clk_gen : PROCESS + begin + if (ac97_reset_n = '0') then + ac97_bit_clk <= '0'; + wait until ac97_reset_n = '1'; + wait for 150 us; + end if; + wait for BIT_CLK_PERIOD/2; + ac97_bit_clk <= not ac97_bit_clk; + END PROCESS; + +STIMULUS: process + + begin + + wait for 3*SYS_CLK_PERIOD; + RST_O <= '0'; + + wait for 200 us; + wait until rising_edge(CLK_O); + + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '0'; + DAT_O <= X"0000_0000"; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O); + STB_O <= '0'; + wait until rising_edge(CLK_O) and ACK_I = '1'; + CYC_O <= '0'; + + wait until rising_edge(CLK_O); + + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '1'; + DAT_O <= X"5555_1000"; + ADDR_O <= X"0000_0800"; + wait until rising_edge(CLK_O); + DAT_O <= X"5555_1001"; + wait until rising_edge(CLK_O); + STB_O <= '0'; + CYC_O <= '0'; + + WAIT; + END PROCESS; +END; diff --git a/lib/ac97_ctrl/src/tb_ac_in.vhd b/lib/ac97_ctrl/src/tb_ac_in.vhd new file mode 100644 index 0000000..359e79b --- /dev/null +++ b/lib/ac97_ctrl/src/tb_ac_in.vhd @@ -0,0 +1,203 @@ + +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 17:33:47 06/05/2007 +-- Design Name: eval_ac +-- Module Name: E:/work/VHDL/eval_ac/tb_eval_ac.vhd +-- Project Name: ac_out +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: ac_out +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY tb_ac_in IS +END tb_ac_in; + +ARCHITECTURE behavior OF tb_ac_in IS + + -- Component Declaration for the Unit Under Test (UUT) + 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; + + constant SYS_CLK_PERIOD : time := 10 ns; + constant BIT_CLK_PERIOD : time := 81.38 ns; + + --Inputs + SIGNAL rst : std_logic := '1'; + SIGNAL clk : std_logic := '0'; + SIGNAL cmd_we : std_logic := '0'; + SIGNAL pcm_in_we : std_logic := '0'; + SIGNAL ac_bit_clk : std_logic := '0'; + SIGNAL cmd_addr : unsigned(19 downto 0) := (others=>'0'); + SIGNAL cmd_data : unsigned(19 downto 0) := (others=>'0'); + SIGNAL pcm_in_addr : unsigned(3 downto 0) := "0011"; + SIGNAL pcm_in_data : unsigned(19 downto 0) := (others=>'0'); + SIGNAL ac_sdata_in : std_logic; + SIGNAL pcm_out_addr : unsigned(3 downto 0) := "0101"; + SIGNAL ac_reset : std_logic := '1'; + + --Outputs + SIGNAL sync_frame : std_logic; + SIGNAL sync_status : std_logic; + SIGNAL sync_tx : std_logic; + SIGNAL ac_sdata_out : std_logic; + SIGNAL ac_ssync : std_logic; + SIGNAL stat_addr : unsigned(19 downto 0); + SIGNAL stat_data : unsigned(19 downto 0); + SIGNAL stat_valid : std_logic; + SIGNAL pcm_out_data : unsigned(19 downto 0); + SIGNAL pcm_out_valid : std_logic; + SIGNAL pcm_out_avail : std_logic; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: ac_in PORT MAP( + rst => rst, + clk => clk, + sync_frame => sync_frame, + sync_status => sync_status, + stat_addr => stat_addr, + stat_data => stat_data, + pcm_out_addr => pcm_out_addr, + pcm_out_data => pcm_out_data, + ac_reset => ac_reset, + ac_bit_clk => ac_bit_clk, + ac_sdata_in => ac_sdata_in, + ac_ssync => ac_ssync + ); + + 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 => pcm_in_addr, + pcm_in_data => pcm_in_data, + pcm_in_we => pcm_in_we, + ac_reset => ac_reset, + ac_bit_clk => ac_bit_clk, + ac_sdata_out => ac_sdata_out, + ac_ssync => ac_ssync + ); + + ac_sdata_in <= ac_sdata_out; + + sys_clk_gen : + PROCESS + BEGIN + wait for SYS_CLK_PERIOD; + clk <= not clk; + END PROCESS; + + bit_clk_gen : + PROCESS + BEGIN + wait for BIT_CLK_PERIOD; + ac_bit_clk <= not ac_bit_clk; + END PROCESS; + + tb_out : PROCESS + BEGIN + + -- Wait 100 ns for global reset to finish + wait for 100*SYS_CLK_PERIOD; + rst <= '0'; + + wait for 100*SYS_CLK_PERIOD; + ac_reset <= '0'; + + wait until rising_edge(clk) and sync_tx = '1'; + wait for 100*SYS_CLK_PERIOD; + cmd_data <= X"12340"; + cmd_addr <= X"8B930"; + + wait until rising_edge(clk); + cmd_we <= '1'; + wait until rising_edge(clk); + cmd_we <= '0'; + + for k in 1 to 10 loop + pcm_in_we <= '0'; + wait until rising_edge(clk) and sync_tx = '1'; + wait for 100*SYS_CLK_PERIOD; + for i in 3 to 12 loop + pcm_in_addr <= to_unsigned(i, 4); + pcm_in_data <= to_unsigned(2048*k + integer(i), 20); + pcm_in_we <= '1'; + wait until rising_edge(clk); + end loop; + end loop; + pcm_in_we <= '0'; + + -- Place stimulus here + + wait; -- will wait forever + END PROCESS; + + tb_in : PROCESS(clk, pcm_out_addr, sync_status) + BEGIN + if rising_edge(clk) then + if sync_status = '1' then + pcm_out_addr <= "0011"; + elsif pcm_out_addr /= "1100" then + pcm_out_addr <= pcm_out_addr + 1; + end if; + end if; + END PROCESS; +END; diff --git a/lib/ac97_ctrl/src/tb_ac_io.vhd b/lib/ac97_ctrl/src/tb_ac_io.vhd new file mode 100644 index 0000000..6f25c1d --- /dev/null +++ b/lib/ac97_ctrl/src/tb_ac_io.vhd @@ -0,0 +1,186 @@ + +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 17:33:47 06/05/2007 +-- Design Name: eval_ac +-- Module Name: E:/work/VHDL/eval_ac/tb_eval_ac.vhd +-- Project Name: ac_out +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: ac_out +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY tb_ac_io IS +END tb_ac_io; + +ARCHITECTURE behavior OF tb_ac_io IS + + -- Component Declaration for the Unit Under Test (UUT) + COMPONENT ac_io + 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 COMPONENT; + + constant SYS_CLK_PERIOD : time := 10 ns; + CONSTANT BIT_CLK_PERIOD : time := 100 ns; +-- constant BIT_CLK_PERIOD : time := 81.38 ns; + + --Inputs + SIGNAL rst : std_logic := '1'; + SIGNAL clk : std_logic := '0'; + SIGNAL acio_ready : std_logic; + SIGNAL cmd_we : std_logic := '0'; + SIGNAL tx_pcm_we : std_logic := '0'; + SIGNAL ac_bit_clk : std_logic := '0'; + SIGNAL cmd_addr : unsigned(19 downto 0) := (others=>'0'); + SIGNAL cmd_data : unsigned(19 downto 0) := (others=>'0'); + SIGNAL tx_pcm_addr : unsigned(3 downto 0) := "0011"; + SIGNAL tx_pcm_data : unsigned(19 downto 0) := (others=>'0'); + SIGNAL ac_sdata_in : std_logic; + SIGNAL rx_pcm_addr : unsigned(3 downto 0) := "0101"; + + --Outputs + SIGNAL slot_valid : unsigned(0 to 12); + SIGNAL sync_strobe : unsigned(0 to 2); + SIGNAL ac_reset_n : std_logic; + SIGNAL ac_sdata_out : std_logic; + SIGNAL ac_ssync : std_logic; + SIGNAL stat_addr : unsigned(19 downto 0); + SIGNAL stat_data : unsigned(19 downto 0); + SIGNAL rx_pcm_data : unsigned(19 downto 0); + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: ac_io PORT MAP( + rst => rst, + clk => clk, + ready => acio_ready, + sync_strobe => sync_strobe, + slot_valid => slot_valid, + stat_addr => stat_addr, + stat_data => stat_data, + rx_pcm_addr => rx_pcm_addr, + rx_pcm_data => rx_pcm_data, + cmd_addr => cmd_addr, + cmd_data => cmd_data, + cmd_we => cmd_we, + tx_pcm_addr => tx_pcm_addr, + tx_pcm_data => tx_pcm_data, + tx_pcm_we => tx_pcm_we, + ac_sdata_in => ac_sdata_in, + ac_bit_clk => ac_bit_clk, + ac_reset_n => ac_reset_n, + ac_sdata_out => ac_sdata_out, + ac_ssync => ac_ssync + ); + + ac_sdata_in <= ac_sdata_out; + + sys_clk_gen : + PROCESS + BEGIN + wait for SYS_CLK_PERIOD; + clk <= not clk; + END PROCESS; + + bit_clk_gen : PROCESS + begin + if (ac_reset_n = '0') then + ac_bit_clk <= '0'; + wait until ac_reset_n = '1'; + wait for 150 us; + end if; + wait for BIT_CLK_PERIOD/2; + ac_bit_clk <= not ac_bit_clk; + END PROCESS; + + tb_out : PROCESS + BEGIN + + -- Wait 100 ns for global reset to finish + wait for 100*SYS_CLK_PERIOD; + rst <= '0'; + + wait until (ac_reset_n = '1'); + + wait until rising_edge(clk) and sync_strobe(2) = '1'; + wait for 100*SYS_CLK_PERIOD; + cmd_data <= X"12340"; + cmd_addr <= X"8B930"; + + wait until rising_edge(clk); + cmd_we <= '1'; + wait until rising_edge(clk); + cmd_we <= '0'; + + for k in 1 to 10 loop + tx_pcm_we <= '0'; + wait until rising_edge(clk) and sync_strobe(2) = '1'; + wait for 10*BIT_CLK_PERIOD; + for i in 3 to 12 loop + tx_pcm_addr <= to_unsigned(i, 4); + tx_pcm_data <= to_unsigned(2048*k + integer(i), 20); + tx_pcm_we <= '1'; + wait until rising_edge(clk); + end loop; + end loop; + tx_pcm_we <= '0'; + + -- Place stimulus here + + wait; -- will wait forever + END PROCESS; + + tb_in : PROCESS(clk, rx_pcm_addr, sync_strobe) + BEGIN + if rising_edge(clk) then + if sync_strobe(1) = '1' then + rx_pcm_addr <= "0011"; + elsif rx_pcm_addr /= "1100" then + rx_pcm_addr <= rx_pcm_addr + 1; + end if; + end if; + END PROCESS; + +END; diff --git a/lib/ac97_ctrl/src/tb_ac_out.vhd b/lib/ac97_ctrl/src/tb_ac_out.vhd new file mode 100644 index 0000000..6f6cb42 --- /dev/null +++ b/lib/ac97_ctrl/src/tb_ac_out.vhd @@ -0,0 +1,149 @@ + +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 17:33:47 06/05/2007 +-- Design Name: eval_ac +-- Module Name: E:/work/VHDL/eval_ac/tb_eval_ac.vhd +-- Project Name: ac_out +-- Target Device: +-- Tool versions: +-- Description: +-- +-- VHDL Test Bench Created by ISE for module: ac_out +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-- Notes: +-- This testbench has been automatically generated using types std_logic and +-- std_logic_vector for the ports of the unit under test. Xilinx recommends +-- that these types always be used for the top-level I/O of a design in order +-- to guarantee that the testbench will bind correctly to the post-implementation +-- simulation model. +-------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY tb_ac_out IS +END tb_ac_out; + +ARCHITECTURE behavior OF tb_ac_out IS + + -- Component Declaration for the Unit Under Test (UUT) + 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; + + constant SYS_CLK_PERIOD : time := 10 ns; + constant BIT_CLK_PERIOD : time := 81.38 ns; + + --Inputs + SIGNAL rst : std_logic := '1'; + SIGNAL clk : std_logic := '0'; + SIGNAL ce : std_logic := '0'; + SIGNAL cmd_we : std_logic := '0'; + SIGNAL pcm_in_we : std_logic := '0'; + SIGNAL ac_bit_clk : std_logic := '0'; + SIGNAL cmd_addr : unsigned(19 downto 0) := (others=>'0'); + SIGNAL cmd_data : unsigned(19 downto 0) := (others=>'0'); + SIGNAL pcm_in_addr : unsigned(3 downto 0) := (others=>'0'); + SIGNAL pcm_in_data : unsigned(19 downto 0) := (others=>'0'); + + --Outputs + SIGNAL sync_tx : std_logic; + SIGNAL ac_reset : std_logic; + SIGNAL ac_sdata_out : std_logic; + SIGNAL ac_ssync : std_logic; + +BEGIN + + -- Instantiate the Unit Under Test (UUT) + uut: 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 => pcm_in_addr, + pcm_in_data => pcm_in_data, + pcm_in_we => pcm_in_we, + ac_reset => ac_reset, + ac_bit_clk => ac_bit_clk, + ac_sdata_out => ac_sdata_out, + ac_ssync => ac_ssync + ); + + sys_clk_gen : + PROCESS + BEGIN + wait for SYS_CLK_PERIOD; + clk <= not clk; + END PROCESS; + + bit_clk_gen : + PROCESS + BEGIN + wait for BIT_CLK_PERIOD; + ac_bit_clk <= not ac_bit_clk; + END PROCESS; + + tb : PROCESS + BEGIN + + -- Wait 100 ns for global reset to finish + wait for 100*SYS_CLK_PERIOD; + rst <= '0'; + + wait for 100*SYS_CLK_PERIOD; + ac_reset <= '0'; + + wait until rising_edge(clk) and sync_tx = '1'; + wait for 100*SYS_CLK_PERIOD; + cmd_data <= X"aaaa0"; + cmd_addr <= X"1DFC0"; + + wait until rising_edge(clk); + cmd_we <= '1'; + wait until rising_edge(clk); + cmd_we <= '0'; + + for k in 1 to 10 loop + pcm_in_we <= '0'; + wait until rising_edge(clk) and sync_tx = '1'; + wait for 100*SYS_CLK_PERIOD; + for i in 3 to 12 loop + pcm_in_addr <= to_unsigned(i, 4); + pcm_in_data <= to_unsigned(2048*k + integer(i), 20); + pcm_in_we <= '1'; + wait until rising_edge(clk); + end loop; + end loop; + pcm_in_we <= '0'; + + -- Place stimulus here + + wait; -- will wait forever + END PROCESS; + +END;