diff --git a/libraries/technology/10gbase_r/sim_10gbase_r.vhd b/libraries/technology/10gbase_r/sim_10gbase_r.vhd index 6c6831aaab690102056faf38621db7f9d6cffcbe..70b51d810b9a44f6cad838ccb5276360160e6c45 100644 --- a/libraries/technology/10gbase_r/sim_10gbase_r.vhd +++ b/libraries/technology/10gbase_r/sim_10gbase_r.vhd @@ -28,10 +28,11 @@ -- . The model uses 10/8 overhead to transport the control signalling. Therefore -- the line rate becomes 12.5 Gbps instead of 10.3125 M for the technology. -LIBRARY IEEE, common_lib, tech_transceiver_lib; +LIBRARY IEEE, common_lib, tech_pll_lib, tech_transceiver_lib; USE IEEE.STD_LOGIC_1164.ALL; USE common_lib.common_pkg.ALL; USE common_lib.common_interface_layers_pkg.ALL; +USE tech_pll_lib.tech_pll_component_pkg.ALL; ENTITY sim_10gbase_r IS GENERIC ( @@ -61,9 +62,10 @@ END sim_10gbase_r; ARCHITECTURE str OF sim_10gbase_r IS + CONSTANT c_tr_clk_period : TIME := tech_pll_clk_156_period; -- 6.400020 ns ~= 156.25 MHz --> model line rate : 156.25 MHz * 10/8 (encoding) * 64b (data width) = 12500 Mbps / lane + CONSTANT c_serdes_data_w : NATURAL := c_xgmii_data_w; -- 64 b CONSTANT c_serdes_ctrl_w : NATURAL := c_xgmii_ctrl_w; -- 8 b - CONSTANT c_serdes_line_rate : NATURAL := 12500; -- Mbps = 156.25 MHz * 10/8 (encoding) * 64b (data width) -- XGMII control bits (one for each XGMII lane): SIGNAL xgmii_tx_c_arr : t_xgmii_c_arr(g_nof_channels-1 DOWNTO 0); @@ -109,8 +111,8 @@ BEGIN u_ser: ENTITY tech_transceiver_lib.sim_transceiver_serializer GENERIC MAP ( - g_data_w => c_serdes_data_w, - g_line_rate => c_serdes_line_rate + g_data_w => c_serdes_data_w, + g_tr_clk_period => c_tr_clk_period ) PORT MAP ( tr_clk => clk_156, @@ -119,13 +121,13 @@ BEGIN tx_in_data => xgmii_tx_d_arr(i), tx_in_ctrl => xgmii_tx_c_arr(i), - tx_out => tx_serial_arr(i) + tx_serial_out => tx_serial_arr(i) ); u_des: ENTITY tech_transceiver_lib.sim_transceiver_deserializer GENERIC MAP ( - g_data_w => c_serdes_data_w, - g_line_rate => c_serdes_line_rate + g_data_w => c_serdes_data_w, + g_tr_clk_period => c_tr_clk_period ) PORT MAP ( tr_clk => clk_156, @@ -134,7 +136,7 @@ BEGIN rx_out_data => xgmii_rx_d_arr(i), rx_out_ctrl => xgmii_rx_c_arr(i), - rx_in => rx_serial_arr(i) + rx_serial_in => rx_serial_arr(i) ); END GENERATE; diff --git a/libraries/technology/transceiver/sim_transceiver_deserializer.vhd b/libraries/technology/transceiver/sim_transceiver_deserializer.vhd index b8daf733873417864dacad4b6f2c44704e2cd5b1..7b8582740b252dfdef45ac428f5c9a236429cfbc 100644 --- a/libraries/technology/transceiver/sim_transceiver_deserializer.vhd +++ b/libraries/technology/transceiver/sim_transceiver_deserializer.vhd @@ -34,22 +34,19 @@ USE common_lib.common_pkg.ALL; ENTITY sim_transceiver_deserializer IS GENERIC( - g_data_w : NATURAL := 32; - g_line_rate : NATURAL := 6250 -- In Mbps. This yields rx_clk = ((8/10)*line_rate)/g_data_w + g_data_w : NATURAL := 32; + g_tr_clk_period : TIME := 6.4 ns ); PORT( - tb_end : IN STD_LOGIC := '0'; -- in simulation stop internal clocks when tb_end='1' to support 'run -all' + tb_end : IN STD_LOGIC := '0'; - tr_clk : IN STD_LOGIC; - tr_rst : IN STD_LOGIC; + tr_clk : IN STD_LOGIC; + tr_rst : IN STD_LOGIC; - rx_clk : OUT STD_LOGIC; - rx_rst : OUT STD_LOGIC; + rx_out_data : OUT STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0); + rx_out_ctrl : OUT STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0); - rx_out_data : OUT STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0); - rx_out_ctrl : OUT STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0); - - rx_in : IN STD_LOGIC + rx_serial_in : IN STD_LOGIC ); END sim_transceiver_deserializer; @@ -57,52 +54,46 @@ END sim_transceiver_deserializer; ARCHITECTURE beh OF sim_transceiver_deserializer IS - CONSTANT c_line_clk_per : TIME := 1000000 ps /g_line_rate; --e.g. 160 ps line clk period for 6250 Mbps - CONSTANT c_usr_nof_bytes : NATURAL := g_data_w / c_byte_w; - - CONSTANT c_rx_clk_per : TIME := c_line_clk_per * ( (g_data_w*10)/8 ); + CONSTANT c_line_clk_period : TIME := g_tr_clk_period * 8 / 10 / g_data_w; + CONSTANT c_tr_clk_period_sim : TIME := c_line_clk_period * g_data_w * 10 / 8; - SIGNAL i_rx_clk : STD_LOGIC := '1'; - SIGNAL i_rx_rst : STD_LOGIC := '1'; + CONSTANT c_nof_bytes_per_data : NATURAL := g_data_w/c_byte_w; BEGIN - rx_clk <= i_rx_clk; - rx_rst <= i_rx_rst; - i_rx_clk <= NOT i_rx_clk OR tb_end AFTER c_rx_clk_per/2; - i_rx_rst <= '0' AFTER c_rx_clk_per*170; - p_deserialize: PROCESS - VARIABLE bit_index : NATURAL; VARIABLE v_rx_out_data : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0); - VARIABLE v_rx_out_ctrl : STD_LOGIC_VECTOR(c_usr_nof_bytes-1 DOWNTO 0); + VARIABLE v_rx_out_ctrl : STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0); BEGIN - WAIT UNTIL tr_rst = '0'; - WAIT UNTIL i_rx_rst = '0' ; - - -- Give TX time to serialize the first word. - WAIT FOR c_rx_clk_per; - - -- Wait for half of a serial clk period so data is stable when sampling - WAIT FOR c_line_clk_per/2; + --rx_out_data <= (OTHERS=>'0'); + rx_out_ctrl <= (OTHERS=>'0'); + WAIT UNTIL tr_rst='0' ; + -- Align to tr_clk + WAIT UNTIL rising_edge(tr_clk); + WHILE tb_end='0' LOOP - -- Start deserializing. Deserialization will be completed on the next rising edge of rx_clk. - FOR byte IN 0 TO c_usr_nof_bytes-1 LOOP - -- Deserialize one byte + -- Wait for half of a serial clk period so data is stable when sampling + WAIT FOR c_line_clk_period/2; + + -- Data word deserialization cycle + FOR byte IN 0 TO c_nof_bytes_per_data-1 LOOP + -- Deserialize each data byte using 10 bits per byte from the line FOR bit IN 0 TO c_byte_w-1 LOOP - WAIT FOR c_line_clk_per; - -- Read one bit and assemble the parallel data word - bit_index := byte*c_byte_w+bit; - v_rx_out_data(bit_index) := rx_in; + v_rx_out_data(byte*c_byte_w+bit) := rx_serial_in; -- Get the 8 data bits of the data byte from the line + WAIT FOR c_line_clk_period; END LOOP; - -- Read the control bit from the line - WAIT FOR c_line_clk_per; - v_rx_out_ctrl(byte) := rx_in; - -- Ignore the unised tenth bit - WAIT FOR c_line_clk_per; + v_rx_out_ctrl(byte) := rx_serial_in; -- Get the 1 control bit from the line for each byte + WAIT FOR c_line_clk_period; + --Ignore tenth bit -- Get the 1 unused tenth bit = '0' from the line + IF byte<c_nof_bytes_per_data-1 THEN + WAIT FOR c_line_clk_period; -- exit loop in last half line clock cycle + END IF; END LOOP; + -- Realign to tr_clk rising edge + WAIT UNTIL rising_edge(tr_clk); + -- End of this deserialization cycle: the rx data word has been assembled. rx_out_data <= v_rx_out_data; rx_out_ctrl <= v_rx_out_ctrl; diff --git a/libraries/technology/transceiver/sim_transceiver_gx.vhd b/libraries/technology/transceiver/sim_transceiver_gx.vhd index a7bc43c3b2fa90e0e6c5bbe0941cd7e2cf3c71a1..5c53913c1fa4d62e888294a235846215d0946fad 100644 --- a/libraries/technology/transceiver/sim_transceiver_gx.vhd +++ b/libraries/technology/transceiver/sim_transceiver_gx.vhd @@ -37,7 +37,7 @@ ENTITY sim_transceiver_gx IS GENERIC( g_data_w : NATURAL; g_nof_gx : NATURAL; - g_mbps : NATURAL; + g_mbps : NATURAL; -- line rate in Mbps so including 10/8 encoding g_tx : BOOLEAN; g_rx : BOOLEAN ); @@ -65,11 +65,12 @@ END sim_transceiver_gx; ARCHITECTURE str OF sim_transceiver_gx IS + CONSTANT c_tr_clk_period : TIME := 1 us * g_data_w * 10 / 8 / g_mbps; + TYPE t_ctrl_2arr IS ARRAY(g_nof_gx-1 DOWNTO 0) OF STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0); SIGNAL tr_rst : STD_LOGIC; - SIGNAL i_tx_clk : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); SIGNAL tx_ready : STD_LOGIC; SIGNAL tx_in_ctrl : t_ctrl_2arr; @@ -77,7 +78,20 @@ ARCHITECTURE str OF sim_transceiver_gx IS BEGIN - tx_clk <= i_tx_clk; + u_areset_tr_rst : ENTITY common_lib.common_areset + GENERIC MAP( + g_rst_level => '1' + ) + PORT MAP( + clk => tr_clk, + in_rst => '0', + out_rst => tr_rst + ); + + tx_clk <= (OTHERS=>tr_clk); + tx_rst <= (OTHERS=>tr_rst); + rx_clk <= (OTHERS=>tr_clk); + rx_rst <= (OTHERS=>tr_rst); p_tx_rdy : PROCESS VARIABLE v_tx_clk_cnt : NATURAL := 0; @@ -85,7 +99,7 @@ BEGIN tx_ready <= '0'; WAIT FOR 1084.8 ns; -- Time until tx_rst (in tr_clk domain) is deasserted: tx init done WHILE v_tx_clk_cnt < 1000 LOOP -- 1000 tx clk cycles until alignment is completed - WAIT UNTIL rising_edge(i_tx_clk(0)); + WAIT UNTIL rising_edge(tr_clk); v_tx_clk_cnt := v_tx_clk_cnt + 1; tx_ready <= '1'; END LOOP; @@ -97,50 +111,42 @@ BEGIN tx_siso_arr(i).ready <= tx_ready; tx_siso_arr(i).xon <= tx_ready; - gen_fanout: FOR j IN g_data_w/c_byte_w-1 DOWNTO 0 GENERATE - tx_in_ctrl(i)(j) <= tx_sosi_arr(i).valid; - END GENERATE; + tx_in_ctrl(i) <= (OTHERS=>tx_sosi_arr(i).valid); u_ser: ENTITY work.sim_transceiver_serializer GENERIC MAP ( - g_data_w => g_data_w, - g_line_rate => g_mbps + g_data_w => g_data_w, + g_tr_clk_period => c_tr_clk_period ) PORT MAP ( - tb_end => tb_end, + tb_end => tb_end, - tr_clk => tr_clk, - tr_rst => tr_rst, + tr_clk => tr_clk, + tr_rst => tr_rst, - tx_clk => i_tx_clk(i), - tx_rst => tx_rst(i), - - tx_in_data => tx_sosi_arr(i).data(g_data_w-1 DOWNTO 0), - tx_in_ctrl => tx_in_ctrl(i), + tx_in_data => tx_sosi_arr(i).data(g_data_w-1 DOWNTO 0), + tx_in_ctrl => tx_in_ctrl(i), - tx_out => tx_dataout(i) + tx_serial_out => tx_dataout(i) ); END GENERATE; gen_rx : IF g_rx = TRUE GENERATE u_des: ENTITY work.sim_transceiver_deserializer GENERIC MAP ( - g_data_w => g_data_w, - g_line_rate => g_mbps + g_data_w => g_data_w, + g_tr_clk_period => c_tr_clk_period ) PORT MAP ( - tb_end => tb_end, + tb_end => tb_end, - tr_clk => tr_clk, - tr_rst => tr_rst, + tr_clk => tr_clk, + tr_rst => tr_rst, - rx_clk => rx_clk(i), - rx_rst => rx_rst(i), + rx_out_data => rx_sosi_arr(i).data(g_data_w-1 DOWNTO 0), + rx_out_ctrl => rx_out_ctrl(i), - rx_out_data => rx_sosi_arr(i).data(g_data_w-1 DOWNTO 0), - rx_out_ctrl => rx_out_ctrl(i), - - rx_in => rx_datain(i) + rx_serial_in => rx_datain(i) ); END GENERATE; @@ -148,15 +154,5 @@ BEGIN END GENERATE; - u_areset_tr_rst : ENTITY common_lib.common_areset - GENERIC MAP( - g_rst_level => '1' - ) - PORT MAP( - clk => tr_clk, - in_rst => '0', - out_rst => tr_rst - ); - END str; diff --git a/libraries/technology/transceiver/sim_transceiver_serializer.vhd b/libraries/technology/transceiver/sim_transceiver_serializer.vhd index e15c40e5532c06eab15b386b8f03b06553f5b442..237c626b148a8875b6aa4d2207dbe4a634c7b2c8 100644 --- a/libraries/technology/transceiver/sim_transceiver_serializer.vhd +++ b/libraries/technology/transceiver/sim_transceiver_serializer.vhd @@ -23,40 +23,48 @@ -- Purpose: -- Basic serializer model for fast transceiver simulation -- Description: --- This model can be connected to the transmitter entity serial --- transmitter output in simulation. As all serializers in the simualation are +-- The model serializes parallel data using 10 serial bits per byte. The two +-- extra bits are used to transfer (XGMII) control. The model can represent +-- any real transceiver encoding scheme (10b/8b, 66b/64b) because it the +-- modelled line rate does not have to be the same as the true line rate. +-- The key feature that the model provides is that the parallel data gets +-- transported via a single 1-bit lane. This allows fast simulation of the +-- link using the true port widths. The model also assumes that the +-- transceivers on both sides of the link use the same tr_clk. Therefore any +-- delay on the link must be an integer number of tr_clk cycles. +-- This model can be connected to the transmitter entity serial transmitter +-- output in simulation. As all serializers in the simualation are -- simultaneously released from reset and share the same transceiver -- reference clock, we don't need to worry about synchronization and can --- simply assign one or more bits per serial group as validity indicator. The most --- straightforward is to mimic 10/8 encoding for as far as data rates and clock --- ratios are concerned (not the encoding itself): +-- simply assign one or more bits per serial group as validity indicator. The +-- most straightforward is to mimic 10/8 encoding for as far as data rates +-- and clock ratios are concerned (not the encoding itself): -- * User data rate = (8/10)*line data rate -- * User clock frequency = User data rate / user data width -- * Serial data block size = 10 bits [9..0] LSb sent first --- * [9] = Unused, '0'., indiced by 'x'. +-- * [9] = Unused, '0'., indiced by 'x' (so 9/8 encoding would suffice too). -- * [8] = Control bit. -- * [7..0] = Data --- * Word/byte alignment is not required because reference clk and rst are global in --- simulation: what gets transmitted first is received first. +-- * Word/byte alignment is not required because reference clk and rst are +-- global in simulation: what gets transmitted first is received first. -- --- The following diagram shows the serialization of the 32-bit word 0x2. The grid of dots --- indicates the bit resolution. Note the 1 serial cycle of delay before the first bit --- is put on the line. +-- The following diagram shows the serialization of the 32-bit word 0x2. The +-- grid of dots indicates the bit resolution. Note the 1 serial cycle of delay +-- before the first bit is put on the line. -- --- . _______________________________________ . . . . . . . . . . . . . . . . . . . . . --- tx_clk _|. . . . . . . . . . . . . . . . . . . .|_________________________________________ --- _ . . _ . . . . . . _ . . . . . . . . . _ . . . . . . . . . _ . . . . . . . . . _ . --- tx_out .|___|.|___________|.|_________________|.|_________________|.|_________________|.|_ --- --- c x 0 1 2 3 4 5 6 7 c x 0 1 2 3 4 5 6 7 c x 0 1 2 3 4 5 6 7 c x 0 1 2 3 4 5 6 7 c x --- |<----- Byte 0 ---->|<----- Byte 1 ---->|<----- Byte 2 ---->|<----- Byte 3 ---->| +-- . _______________________________________ . . . . . . . . . . . . . . . . . . . . . +-- tr_clk _|. . . . . . . . . . . . . . . . . . . .|_________________________________________ +-- _ . . _ . . . . . . _ . . . . . . . . . _ . . . . . . . . . _ . . . . . . . . . _ . +-- tx_serial_out .|___|.|___________|.|_________________|.|_________________|.|_________________|.|_ +-- +-- c x 0 1 2 3 4 5 6 7 c x 0 1 2 3 4 5 6 7 c x 0 1 2 3 4 5 6 7 c x 0 1 2 3 4 5 6 7 c x +-- |<----- Byte 0 ---->|<----- Byte 1 ---->|<----- Byte 2 ---->|<----- Byte 3 ---->| -- -- Remarks: --- . Requirements: --- . All serializers in the simualation should be simultaneously released from --- reset and have to share the same transceiver reference clock. --- . This serializer is used in the tr_nonbonded module as a behavioural model --- inside phy_gx.vhd. +-- . All serializers in the simualation should be simultaneously released from +-- reset and have to share the same transceiver reference clock. +-- . The number of line clock cycles to transmit one data word fits within 1 +-- tr_clk period. After every data word the data is realigned to the tr_clk. LIBRARY IEEE, common_lib; @@ -66,22 +74,19 @@ USE common_lib.common_pkg.ALL; ENTITY sim_transceiver_serializer IS GENERIC( - g_data_w : NATURAL := 32; - g_line_rate : NATURAL := 6250 -- In Mbps. This yields tx_clk period = ((8/10)*line_rate)/g_data_w + g_data_w : NATURAL := 32; + g_tr_clk_period : TIME := 6.4 ns ); PORT( - tb_end : IN STD_LOGIC := '0'; -- in simulation stop internal clocks when tb_end='1' to support 'run -all' + tb_end : IN STD_LOGIC := '0'; - tr_clk : IN STD_LOGIC; - tr_rst : IN STD_LOGIC; + tr_clk : IN STD_LOGIC; + tr_rst : IN STD_LOGIC; - tx_clk : OUT STD_LOGIC; - tx_rst : OUT STD_LOGIC; + tx_in_data : IN STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0); + tx_in_ctrl : IN STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0); - tx_in_data : IN STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0); - tx_in_ctrl : IN STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0); - - tx_out : OUT STD_LOGIC + tx_serial_out : OUT STD_LOGIC ); END sim_transceiver_serializer; @@ -89,52 +94,46 @@ END sim_transceiver_serializer; ARCHITECTURE beh OF sim_transceiver_serializer IS - CONSTANT c_line_clk_per : TIME := 1000000 ps /g_line_rate; --e.g. 160 ps line clk period for 6250 Mbps - CONSTANT c_usr_nof_bytes : NATURAL := g_data_w / c_byte_w; - CONSTANT c_tx_clk_per : TIME := c_line_clk_per * ( (g_data_w*10)/8 ); + CONSTANT c_line_clk_period : TIME := g_tr_clk_period * 8 / 10 / g_data_w; + CONSTANT c_tr_clk_period_sim : TIME := c_line_clk_period * g_data_w * 10 / 8; - SIGNAL i_tx_clk : STD_LOGIC := '1'; - SIGNAL i_tx_rst : STD_LOGIC := '1'; + CONSTANT c_nof_bytes_per_data : NATURAL := g_data_w / c_byte_w; BEGIN - tx_clk <= i_tx_clk; - tx_rst <= i_tx_rst; - i_tx_clk <= NOT i_tx_clk OR tb_end AFTER c_tx_clk_per/2; - i_tx_rst <= '0' AFTER c_tx_clk_per*170; - p_serialize: PROCESS - VARIABLE bit_index : NATURAL; + VARIABLE v_tx_in_data : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0); + VARIABLE v_tx_in_ctrl : STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0); BEGIN - tx_out <= '0'; - WAIT UNTIL tr_rst = '0'; - WAIT UNTIL i_tx_rst = '0' ; + tx_serial_out <= '0'; + WAIT UNTIL tr_rst='0'; - -- Deserializer waits for c_line_clk_per/2 - WAIT FOR c_line_clk_per; + -- Align to tr_clk + WAIT UNTIL rising_edge(tr_clk); + v_tx_in_data := tx_in_data; + v_tx_in_ctrl := tx_in_ctrl; WHILE tb_end='0' LOOP - -- New serialization cycle - FOR byte IN 0 TO c_usr_nof_bytes-1 LOOP - -- Put a data byte on the line + -- Data word serialization cycle + FOR byte IN 0 TO c_nof_bytes_per_data-1 LOOP + -- Serialize each data byte using 10 bits per byte on the line FOR bit IN 0 TO c_byte_w-1 LOOP - -- Put a data bit on the line - tx_out <= tx_in_data(byte*c_byte_w+bit); - -- Wait for one line clk period. The sum of all of these line clock cycles automatically - -- creates the correct tx_clk period - for example if g_data_w = 32 and g_line_rate = 5000, - -- 40 (32 bits incl. 10/8 overhead) bits have to be serialized, one bit per 200 ps period. - -- These settings would yield a tx_clk period of 40*200 ps = 8 ns (125 MHz). - WAIT FOR c_line_clk_per; + tx_serial_out <= v_tx_in_data(byte*c_byte_w+bit); -- Put the 8 data bits of the data byte on the line + WAIT FOR c_line_clk_period; END LOOP; - -- Put the control bit on the line for each byte - tx_out <= tx_in_ctrl(byte); - -- Wait for one line clk period - WAIT FOR c_line_clk_per; - -- Put the unused tenth bit = '0' on the line - tx_out <= '0'; - -- Wait for one line clk period - WAIT FOR c_line_clk_per; + tx_serial_out <= v_tx_in_ctrl(byte); -- Put the 1 control bit on the line for each byte + WAIT FOR c_line_clk_period; + tx_serial_out <= '0'; -- Put the 1 unused tenth bit = '0' on the line + IF byte<c_nof_bytes_per_data-1 THEN + WAIT FOR c_line_clk_period; -- exit loop in last line clock cycle + END IF; END LOOP; + + -- Realign to tr_clk rising edge if necessary + WAIT UNTIL rising_edge(tr_clk); + + v_tx_in_data := tx_in_data; + v_tx_in_ctrl := tx_in_ctrl; END LOOP; END PROCESS; diff --git a/libraries/technology/transceiver/tb_sim_transceiver_serdes.vhd b/libraries/technology/transceiver/tb_sim_transceiver_serdes.vhd index 51d6587d65c89cb0d02f99627fe9cbdb01e8b203..cd172b6cf150a63194d54406e3d174b7c5ad10ba 100644 --- a/libraries/technology/transceiver/tb_sim_transceiver_serdes.vhd +++ b/libraries/technology/transceiver/tb_sim_transceiver_serdes.vhd @@ -25,10 +25,10 @@ -- Description: -- Data generator -> Serializer -> Deserializer -> Data verification -- Usage: --- as x --- run 2200 ns +-- as 10 +-- run -all -- Observe: --- . user tx_in on serializer == user rx_out on deserializer +-- . user tx_in_data on serializer == user rx_out_data on deserializer -- . serial_line carries 4 bytes per serialized word. Each -- byte is followed by its 2 valid bits and is sent LSb first. @@ -43,104 +43,99 @@ END ENTITY tb_sim_transceiver_serdes; ARCHITECTURE tb of tb_sim_transceiver_serdes IS + CONSTANT c_data_w : NATURAL := 32; CONSTANT c_tr_clk_period : TIME := 6.4 ns; -- 156.25 MHz - CONSTANT c_data_w : NATURAL := 32; - CONSTANT c_line_rate : NATURAL := 6250; + SIGNAL tb_end : STD_LOGIC := '0'; + + SIGNAL tr_clk : STD_LOGIC := '0'; + SIGNAL tr_rst : STD_LOGIC := '1'; - SIGNAL enable : STD_LOGIC := '1'; - SIGNAL ready : STD_LOGIC; + SIGNAL tx_enable : STD_LOGIC := '1'; + SIGNAL tx_ready : STD_LOGIC; - SIGNAL tr_clk : STD_LOGIC := '0'; - SIGNAL tr_rst : STD_LOGIC := '1'; + SIGNAL tx_in_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0); + SIGNAL tx_in_val : STD_LOGIC; + SIGNAL tx_in_ctrl : STD_LOGIC_VECTOR(c_data_w/c_byte_w-1 DOWNTO 0); - SIGNAL tx_in : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0); - SIGNAL tx_in_val : STD_LOGIC; - SIGNAL tx_in_ctrl : STD_LOGIC_VECTOR(c_data_w/c_byte_w-1 DOWNTO 0); + SIGNAL serial_line : STD_LOGIC; - SIGNAL tx_clk : STD_LOGIC; - SIGNAL tx_rst : STD_LOGIC; - - SIGNAL serial_line : STD_LOGIC; - - SIGNAL rx_clk : STD_LOGIC; - SIGNAL rx_rst : STD_LOGIC; - - SIGNAL rx_out : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0); - SIGNAL rx_out_val : STD_LOGIC; - SIGNAL rx_out_ctrl : STD_LOGIC_VECTOR(c_data_w/c_byte_w-1 DOWNTO 0); - - SIGNAL verify_en : STD_LOGIC := '0'; - SIGNAL rd_ready : STD_LOGIC; - SIGNAL prev_rx_out : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0); + SIGNAL rx_out_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0); + SIGNAL rx_out_val : STD_LOGIC; + SIGNAL rx_out_ctrl : STD_LOGIC_VECTOR(c_data_w/c_byte_w-1 DOWNTO 0); + SIGNAL prev_rx_out_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0); + SIGNAL verify_en : STD_LOGIC := '0'; + SIGNAL rd_ready : STD_LOGIC := '1'; BEGIN - tr_clk <= NOT tr_clk AFTER c_tr_clk_period/2; + p_tb_end : PROCESS + BEGIN + WAIT FOR c_tr_clk_period*300; + + -- Stop the simulation + tb_end <= '1'; + ASSERT FALSE REPORT "Simulation finished." SEVERITY NOTE; + WAIT; + END PROCESS; + + tr_clk <= NOT tr_clk OR tb_end AFTER c_tr_clk_period/2; tr_rst <= '0' AFTER c_tr_clk_period*10; - p_ready: PROCESS + p_tx_ready: PROCESS BEGIN - ready <= '0'; - WAIT UNTIL tx_rst = '0'; - WHILE TRUE LOOP - ready <= '1'; + tx_ready <= '0'; + WAIT UNTIL tr_rst = '0'; + WHILE tb_end='0' LOOP + tx_ready <= '1'; WAIT FOR c_tr_clk_period*50; - ready <= '0'; + tx_ready <= '0'; WAIT FOR c_tr_clk_period*50; END LOOP; END PROCESS; - -- Model FIFO output with c_rl = 1 and counter data starting at 0 - proc_common_gen_data(1, 0, tx_rst, tx_clk, enable, ready, tx_in, tx_in_val); + -- Generate Tx data output with c_rl = 1 and counter data starting at 0 + proc_common_gen_data(1, 0, tr_rst, tr_clk, tx_enable, tx_ready, tx_in_data, tx_in_val); - gen_fanout: FOR i IN c_data_w/c_byte_w-1 DOWNTO 0 GENERATE - tx_in_ctrl(i) <= tx_in_val; - END GENERATE; + tx_in_ctrl <= (OTHERS=>tx_in_val); u_ser: ENTITY work.sim_transceiver_serializer GENERIC MAP ( - g_data_w => c_data_w, - g_line_rate => c_line_rate + g_data_w => c_data_w, + g_tr_clk_period => c_tr_clk_period ) PORT MAP ( - + tb_end => tb_end, tr_clk => tr_clk, tr_rst => tr_rst, - tx_clk => tx_clk, - tx_rst => tx_rst, - - tx_in_data => tx_in, + tx_in_data => tx_in_data, tx_in_ctrl => tx_in_ctrl, - tx_out => serial_line + tx_serial_out => serial_line ); u_des: ENTITY work.sim_transceiver_deserializer GENERIC MAP ( - g_data_w => c_data_w, - g_line_rate => c_line_rate + g_data_w => c_data_w, + g_tr_clk_period => c_tr_clk_period ) PORT MAP ( - + tb_end => tb_end, tr_clk => tr_clk, tr_rst => tr_rst, - rx_clk => rx_clk, - rx_rst => rx_rst, - - rx_out_data => rx_out, + rx_out_data => rx_out_data, rx_out_ctrl => rx_out_ctrl, - rx_in => serial_line + rx_serial_in => serial_line ); p_verify_en: PROCESS BEGIN verify_en <= '0'; - WAIT UNTIL rx_rst = '0'; + WAIT UNTIL tr_rst = '0'; WAIT FOR c_tr_clk_period*5; verify_en <= '1'; WAIT; @@ -149,6 +144,6 @@ BEGIN rx_out_val <= andv(rx_out_ctrl); -- Verify dut output incrementing data - proc_common_verify_data(1, rx_clk, verify_en, rd_ready, rx_out_val, rx_out, prev_rx_out); + proc_common_verify_data(1, tr_clk, verify_en, rd_ready, rx_out_val, rx_out_data, prev_rx_out_data); END tb; diff --git a/libraries/technology/xaui/sim_xaui.vhd b/libraries/technology/xaui/sim_xaui.vhd index 10ca0fd8c9ec33227f73a6a2dc2b07abb0bd034e..24b8243bd6a7b7790489202e805a652274cf470c 100644 --- a/libraries/technology/xaui/sim_xaui.vhd +++ b/libraries/technology/xaui/sim_xaui.vhd @@ -76,9 +76,10 @@ END sim_xaui; ARCHITECTURE wrap OF sim_xaui IS + CONSTANT c_tr_clk_period : TIME := 6.4 ns; -- 156.25 MHz --> model line rate : 156.25 MHz * 10/8 (encoding) * 64b (data width) / 4 (XAUI lanes) = 3125 Mbps / lane + CONSTANT c_xaui_serdes_data_w : NATURAL := c_xgmii_data_w / c_nof_xaui_lanes; -- = 16b = 64 b / 4 CONSTANT c_xaui_serdes_ctrl_w : NATURAL := c_xgmii_ctrl_w / c_nof_xaui_lanes; -- = 2b = 8 b / 4 - CONSTANT c_xaui_serdes_line_rate : NATURAL := 3125; -- Mbps = 156.25 MHz * 10/8 (encoding) * 64b (data width) / 4 (XAUI lanes) -- XGMII control bits (one for each XGMII lane): SIGNAL xgmii_tx_c_arr : t_xgmii_c_arr(g_nof_xaui-1 DOWNTO 0); @@ -144,8 +145,8 @@ BEGIN u_ser: ENTITY tech_transceiver_lib.sim_transceiver_serializer GENERIC MAP ( - g_data_w => c_xaui_serdes_data_w, - g_line_rate => c_xaui_serdes_line_rate + g_data_w => c_xaui_serdes_data_w, + g_tr_clk_period => c_tr_clk_period ) PORT MAP ( tr_clk => tr_clk, @@ -154,13 +155,13 @@ BEGIN tx_in_data => xgmii_tx_d_arr(i)(j*c_xaui_serdes_data_w+c_xaui_serdes_data_w-1 DOWNTO j*c_xaui_serdes_data_w), tx_in_ctrl => xgmii_tx_c_arr(i)(j*c_xaui_serdes_ctrl_w+c_xaui_serdes_ctrl_w-1 DOWNTO j*c_xaui_serdes_ctrl_w), - tx_out => xaui_tx_arr(i)(j) + tx_serial_out => xaui_tx_arr(i)(j) ); u_des: ENTITY tech_transceiver_lib.sim_transceiver_deserializer GENERIC MAP ( - g_data_w => c_xaui_serdes_data_w, - g_line_rate => c_xaui_serdes_line_rate + g_data_w => c_xaui_serdes_data_w, + g_tr_clk_period => c_tr_clk_period ) PORT MAP ( tr_clk => tr_clk, @@ -169,7 +170,7 @@ BEGIN rx_out_data => xgmii_rx_d_arr(i)(j*c_xaui_serdes_data_w+c_xaui_serdes_data_w-1 DOWNTO j*c_xaui_serdes_data_w), rx_out_ctrl => xgmii_rx_c_arr(i)(j*c_xaui_serdes_ctrl_w+c_xaui_serdes_ctrl_w-1 DOWNTO j*c_xaui_serdes_ctrl_w), - rx_in => xaui_rx_arr(i)(j) + rx_serial_in => xaui_rx_arr(i)(j) ); END GENERATE;