-- -- Downlink Testbench -- -- -- Matt Warren Aug 2016 -- -- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library downlink; use downlink.lcb_pkg_globals.all; entity lcbtst_tester is port( cmdfrm_ready_o : out std_logic; cmd_gen_busy_i : in std_logic; cmdfrm_o : out std_logic_vector(48 downto 0); dut_hccid_o : out std_logic_vector(4 downto 0); dut_abcid_o : out std_logic_vector(3 downto 0); encoder_hccid_o : out std_logic_vector(4 downto 0); enc_frame_sync_i : in std_logic_vector(1 downto 0); rb_busy_o : out std_logic; ser_o : out std_logic; l0a_o : out std_logic; bcr_o : out std_logic; tag_o : out std_logic_vector(6 downto 0); clk160_o : out std_logic; clk40_o : out std_logic; rstb_o : out std_logic; rst_o : out std_logic ); -- Declarations end entity lcbtst_tester; -- architecture sim of lcbtst_tester is constant POST_CLK_DELAY : time := 50 ps; signal clk : std_logic := '0'; signal clk160 : std_logic := '1'; signal rst : std_logic; signal ser : std_logic; signal l0a : std_logic; signal bcr : std_logic; signal tag : std_logic_vector(6 downto 0); signal dbg_l0a_map : std_logic_vector(3 downto 0); signal dbg_tag : std_logic_vector(6 downto 0); signal dbg_l0a_sr : std_logic_vector(3 downto 0); signal dbg_frame : std_logic_vector(15 downto 0); signal dbg_data6b0 : std_logic_vector(5 downto 0); signal dbg_data6b1 : std_logic_vector(5 downto 0); signal dbg_n : integer; signal dbg_x : integer; signal dbg_y : integer; signal dbg_cmdword : std_logic_vector(48 downto 0); begin rst_o <= rst; rstb_o <= not rst; clk <= not(clk) after 12500 ps; clk40_o <= clk; clk160 <= not(clk160) after 3125 ps; clk160_o <= clk160; ser_o <= ser after 3125 ps; l0a_o <= l0a; bcr_o <= bcr; tag_o <= tag; dbg_l0a_map <= dbg_data6b0(4 downto 1); dbg_tag <= dbg_data6b0(0) & dbg_data6b1; --====================================================================== simulation : process -------------------------------------------------- -- Procedures -------------------------------------------------- procedure WaitClks (nclks : in integer := 1) is begin for waitclkloops in 1 to nclks loop wait until rising_edge(clk); wait for POST_CLK_DELAY; end loop; end procedure; ---------------------------------------------------- procedure WaitClk is begin WaitClks(1); end procedure; ------------------------------------------------------ procedure WaitClk160 is begin wait until rising_edge(clk160); wait for POST_CLK_DELAY; end procedure; ----------------------------------------------------------------------- ----------------------------------------------------------------------- procedure TagIncrement is begin if (tag = "1111111") then tag <= "0000000"; else tag <= tag + '1'; end if; end TagIncrement; ------------------------------------------------------ procedure SendRawFrame(frame : in std_logic_vector(15 downto 0)) is begin dbg_frame <= frame; for n in 0 to 15 loop ser <= frame(15-n); WaitClk160; end loop; dbg_frame <= (others => '0'); end procedure; ---------------------------------------------------- ----------------------------------------------------------------------- ---------------------------------------------------- procedure SendCmdFrame(cmdword : in std_logic_vector(48 downto 0) := '0' & x"000000000000"; hccid : in std_logic_vector(4 downto 0) := "11111" ) is variable data6b0 : std_logic_vector(5 downto 0); variable data6b1 : std_logic_vector(5 downto 0); begin dbg_cmdword <= cmdword; -- All built around 7b per symbol needing 8 symbols = 56b commands SendRawFrame(MAP_K_8B(2) & MAP_6B_8B(conv_integer('0' & hccid))); data6b0(5 downto 1) := "00000"; -- aka this is a command frame for n in 0 to 6 loop data6b0(0) := cmdword(49-n*7+6); -- msb data6b1 := cmdword(49-n*7+5 downto 49-n*7+0); -- lsbs dbg_data6b0 <= data6b0; dbg_data6b1 <= data6b1; SendRawFrame(MAP_6B_8B(conv_integer(data6b0)) & MAP_6B_8B(conv_integer(data6b1))); end loop; SendRawFrame(MAP_K_8B(3) & SYMB_CMD_END); dbg_data6b0 <= (others => '0'); dbg_data6b1 <= (others => '0'); end procedure; ---------------------------------------------------- ------------------------------------------------------ procedure SendIdleFrames(nframes : in integer) is begin for n in 1 to nframes loop SendRawFrame(IDLE_FRAME); end loop; end procedure; ---------------------------------------------------- procedure SendL0AFrame(l0a_map : in std_logic_vector(3 downto 0) := "0001"; tag : in integer := 16#12#; bcr : integer := 0) is variable data6b0 : std_logic_vector(5 downto 0); variable data6b1 : std_logic_vector(5 downto 0); variable tag_slv : std_logic_vector(6 downto 0); begin tag_slv := conv_std_logic_vector(tag, 7); -- default data6b0(5) := '0'; if (bcr = 1) then data6b0(5) := '1'; end if; data6b0(4 downto 1) := l0a_map; data6b0(0) := tag_slv(6); data6b1 := tag_slv(5 downto 0); dbg_data6b0 <= data6b0; dbg_data6b1 <= data6b1; SendRawFrame(MAP_6B_8B(conv_integer(data6b0)) & MAP_6B_8B(conv_integer(data6b1))); dbg_data6b0 <= (others => '0'); dbg_data6b1 <= (others => '0'); end procedure; ---------------------------------------------------- procedure SendL0APattern(pattern : in std_logic_vector(15 downto 0) := x"0001"; bcr_pattern : in std_logic_vector(15 downto 0) := x"0000") is begin for a in 0 to 15 loop l0a <= pattern(15-a); bcr <= bcr_pattern(15-a); WaitClk; if (pattern(15-a) = '1') then TagIncrement; end if; end loop; l0a <= '0'; bcr <= '0'; end procedure; ---------------------------------------------------- --=========================================================================== --=========================================================================== procedure DecoderTest is begin -- Align at center of BCO WaitClk; WaitClk160; WaitClk160; SendIdleFrames(32); --SendRawFrame(x"0000"); SendIdleFrames(20); -- Need to recheck the below since moving to 7*7b -- 0081840A18388 = 2 3 4 5 6 7 8 in 7 bits per digit transposed to 8b -- 02450B183470F = 9 a b c d e f -- 1C7973E9D7B77 = 71 72 73 74 75 76 77 SendCmdFrame('0' & x"081840A18388", "10001"); SendIdleFrames(4); SendCmdFrame('0' & x"081840A18388", "00001"); SendIdleFrames(4); SendCmdFrame('1' & x"C7973E9D7B77", "10001"); SendIdleFrames(4); for n in 10 to 14 loop SendL0AFrame("0010", n); for i in 0 to 1 loop SendRawFrame(IDLE_FRAME); end loop; end loop; for n in 10 to 14 loop SendL0AFrame("1010", n*2); for i in 0 to 1 loop SendRawFrame(IDLE_FRAME); end loop; end loop; for n in 10 to 14 loop SendL0AFrame("0101", n*2); for i in 0 to 1 loop SendRawFrame(IDLE_FRAME); end loop; end loop; for n in 10 to 14 loop SendL0AFrame("0011", n*2); for i in 0 to 1 loop SendRawFrame(IDLE_FRAME); end loop; end loop; for n in 10 to 14 loop SendL0AFrame("0111", n*3); for i in 0 to 1 loop SendRawFrame(IDLE_FRAME); end loop; end loop; for n in 0 to 4 loop SendL0AFrame("1111", n*4); for i in 0 to 1 loop SendRawFrame(IDLE_FRAME); end loop; end loop; end procedure; --============================================================================ begin -- Init ---------------------------- rst <= '1'; ser <= '0'; l0a <= '0'; bcr <= '0'; tag <= "0000000"; cmdfrm_ready_o <= '0'; cmdfrm_o <= '0' & x"000000000000"; encoder_hccid_o <= "10001"; dut_hccid_o <= "10001"; dut_abcid_o <= "1001"; rb_busy_o <= '0'; WaitClks(10); rst <= '0'; WaitClks(10); bcr <= '1'; WaitClk; bcr <= '0'; WaitClks(10); -------------------------------------- ----Directly driving Decoder -- DecoderTest; -- Drive Encoder ------------------------------------------------------r bcr <= '1'; WaitClk; bcr <= '0'; WaitClks(9); -- Setting alignment of L0As wrt BCR - makes for clearer debug WaitClks(8*20); -- Enough IDLEs to achieve lock in HCC and ABC -- align to frame - so BCR is correct wait until enc_frame_sync_i = "11"; WaitClk; SendL0APattern("1110000000000000", "0001000000000000"); WaitClks(4*4); -- Send Commands ----------------------------------------------------------- cmdfrm_ready_o <= '1'; cmdfrm_o <= '1' & x"fc9012345678"; wait until cmd_gen_busy_i = '1'; cmdfrm_ready_o <= '0'; WaitClks(40); SendL0APattern("1110000000000000"); WaitClks(4*4); encoder_hccid_o <= "00001"; --wait until cmd_gen_busy_i = '0'; cmdfrm_ready_o <= '1'; cmdfrm_o <= '1' & x"fc9012345678"; wait until cmd_gen_busy_i = '1'; cmdfrm_ready_o <= '0'; WaitClks(40); SendL0APattern("1110000000000000"); WaitClks(4*4); encoder_hccid_o <= "10001"; --wait until cmd_gen_busy_i = '0'; cmdfrm_ready_o <= '1'; cmdfrm_o <= '1' & x"ac9012345678"; wait until cmd_gen_busy_i = '1'; cmdfrm_ready_o <= '0'; WaitClks(40); SendL0APattern("1000100010000000"); WaitClks(4*4); -- overlap with l0A now .. encoder_hccid_o <= "10001"; -- wait until cmd_gen_busy_i = '0'; cmdfrm_ready_o <= '1'; cmdfrm_o <= '1' & x"9c9012345678"; wait until cmd_gen_busy_i = '1'; cmdfrm_ready_o <= '0'; -- Send L0As (and BCRs, but this is automatic) -------------------------------------------------------------- -- align to LCB frame wait until enc_frame_sync_i = "11"; WaitClk; for n in 0 to 9 loop SendL0APattern("1110000000000000"); WaitClks(4*4); end loop; for n in 0 to 9 loop SendL0APattern("1110000000000000", "0001000000000000"); WaitClks(4*4); end loop; for n in 0 to 9 loop SendL0APattern("1110110010000000", x"1111"); WaitClks(4*4); end loop; WaitClks(1000); wait; end process; end architecture sim;