Skip to content
Snippets Groups Projects
Commit c931eba7 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Use tr_clk in transceiver model.

parent 7dfef788
No related branches found
No related tags found
No related merge requests found
...@@ -28,10 +28,11 @@ ...@@ -28,10 +28,11 @@
-- . The model uses 10/8 overhead to transport the control signalling. Therefore -- . 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. -- 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 IEEE.STD_LOGIC_1164.ALL;
USE common_lib.common_pkg.ALL; USE common_lib.common_pkg.ALL;
USE common_lib.common_interface_layers_pkg.ALL; USE common_lib.common_interface_layers_pkg.ALL;
USE tech_pll_lib.tech_pll_component_pkg.ALL;
ENTITY sim_10gbase_r IS ENTITY sim_10gbase_r IS
GENERIC ( GENERIC (
...@@ -61,9 +62,10 @@ END sim_10gbase_r; ...@@ -61,9 +62,10 @@ END sim_10gbase_r;
ARCHITECTURE str OF sim_10gbase_r IS 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_data_w : NATURAL := c_xgmii_data_w; -- 64 b
CONSTANT c_serdes_ctrl_w : NATURAL := c_xgmii_ctrl_w; -- 8 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): -- XGMII control bits (one for each XGMII lane):
SIGNAL xgmii_tx_c_arr : t_xgmii_c_arr(g_nof_channels-1 DOWNTO 0); SIGNAL xgmii_tx_c_arr : t_xgmii_c_arr(g_nof_channels-1 DOWNTO 0);
...@@ -110,7 +112,7 @@ BEGIN ...@@ -110,7 +112,7 @@ BEGIN
u_ser: ENTITY tech_transceiver_lib.sim_transceiver_serializer u_ser: ENTITY tech_transceiver_lib.sim_transceiver_serializer
GENERIC MAP ( GENERIC MAP (
g_data_w => c_serdes_data_w, g_data_w => c_serdes_data_w,
g_line_rate => c_serdes_line_rate g_tr_clk_period => c_tr_clk_period
) )
PORT MAP ( PORT MAP (
tr_clk => clk_156, tr_clk => clk_156,
...@@ -119,13 +121,13 @@ BEGIN ...@@ -119,13 +121,13 @@ BEGIN
tx_in_data => xgmii_tx_d_arr(i), tx_in_data => xgmii_tx_d_arr(i),
tx_in_ctrl => xgmii_tx_c_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 u_des: ENTITY tech_transceiver_lib.sim_transceiver_deserializer
GENERIC MAP ( GENERIC MAP (
g_data_w => c_serdes_data_w, g_data_w => c_serdes_data_w,
g_line_rate => c_serdes_line_rate g_tr_clk_period => c_tr_clk_period
) )
PORT MAP ( PORT MAP (
tr_clk => clk_156, tr_clk => clk_156,
...@@ -134,7 +136,7 @@ BEGIN ...@@ -134,7 +136,7 @@ BEGIN
rx_out_data => xgmii_rx_d_arr(i), rx_out_data => xgmii_rx_d_arr(i),
rx_out_ctrl => xgmii_rx_c_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; END GENERATE;
......
...@@ -35,21 +35,18 @@ USE common_lib.common_pkg.ALL; ...@@ -35,21 +35,18 @@ USE common_lib.common_pkg.ALL;
ENTITY sim_transceiver_deserializer IS ENTITY sim_transceiver_deserializer IS
GENERIC( GENERIC(
g_data_w : NATURAL := 32; g_data_w : NATURAL := 32;
g_line_rate : NATURAL := 6250 -- In Mbps. This yields rx_clk = ((8/10)*line_rate)/g_data_w g_tr_clk_period : TIME := 6.4 ns
); );
PORT( 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_clk : IN STD_LOGIC;
tr_rst : 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_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_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; END sim_transceiver_deserializer;
...@@ -57,52 +54,46 @@ END sim_transceiver_deserializer; ...@@ -57,52 +54,46 @@ END sim_transceiver_deserializer;
ARCHITECTURE beh OF sim_transceiver_deserializer IS 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_line_clk_period : TIME := g_tr_clk_period * 8 / 10 / g_data_w;
CONSTANT c_usr_nof_bytes : NATURAL := g_data_w / c_byte_w; CONSTANT c_tr_clk_period_sim : TIME := c_line_clk_period * g_data_w * 10 / 8;
CONSTANT c_rx_clk_per : TIME := c_line_clk_per * ( (g_data_w*10)/8 );
SIGNAL i_rx_clk : STD_LOGIC := '1'; CONSTANT c_nof_bytes_per_data : NATURAL := g_data_w/c_byte_w;
SIGNAL i_rx_rst : STD_LOGIC := '1';
BEGIN 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 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_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 BEGIN
--rx_out_data <= (OTHERS=>'0');
rx_out_ctrl <= (OTHERS=>'0');
WAIT UNTIL tr_rst='0' ; WAIT UNTIL tr_rst='0' ;
WAIT UNTIL i_rx_rst = '0' ;
-- Give TX time to serialize the first word. -- Align to tr_clk
WAIT FOR c_rx_clk_per; WAIT UNTIL rising_edge(tr_clk);
WHILE tb_end='0' LOOP
-- Wait for half of a serial clk period so data is stable when sampling -- Wait for half of a serial clk period so data is stable when sampling
WAIT FOR c_line_clk_per/2; WAIT FOR c_line_clk_period/2;
WHILE tb_end='0' LOOP -- Data word deserialization cycle
-- Start deserializing. Deserialization will be completed on the next rising edge of rx_clk. FOR byte IN 0 TO c_nof_bytes_per_data-1 LOOP
FOR byte IN 0 TO c_usr_nof_bytes-1 LOOP -- Deserialize each data byte using 10 bits per byte from the line
-- Deserialize one byte
FOR bit IN 0 TO c_byte_w-1 LOOP FOR bit IN 0 TO c_byte_w-1 LOOP
WAIT FOR c_line_clk_per; v_rx_out_data(byte*c_byte_w+bit) := rx_serial_in; -- Get the 8 data bits of the data byte from the line
-- Read one bit and assemble the parallel data word WAIT FOR c_line_clk_period;
bit_index := byte*c_byte_w+bit;
v_rx_out_data(bit_index) := rx_in;
END LOOP; END LOOP;
-- Read the control bit from the line v_rx_out_ctrl(byte) := rx_serial_in; -- Get the 1 control bit from the line for each byte
WAIT FOR c_line_clk_per; WAIT FOR c_line_clk_period;
v_rx_out_ctrl(byte) := rx_in; --Ignore tenth bit -- Get the 1 unused tenth bit = '0' from the line
-- Ignore the unised tenth bit IF byte<c_nof_bytes_per_data-1 THEN
WAIT FOR c_line_clk_per; WAIT FOR c_line_clk_period; -- exit loop in last half line clock cycle
END IF;
END LOOP; 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. -- End of this deserialization cycle: the rx data word has been assembled.
rx_out_data <= v_rx_out_data; rx_out_data <= v_rx_out_data;
rx_out_ctrl <= v_rx_out_ctrl; rx_out_ctrl <= v_rx_out_ctrl;
......
...@@ -37,7 +37,7 @@ ENTITY sim_transceiver_gx IS ...@@ -37,7 +37,7 @@ ENTITY sim_transceiver_gx IS
GENERIC( GENERIC(
g_data_w : NATURAL; g_data_w : NATURAL;
g_nof_gx : NATURAL; g_nof_gx : NATURAL;
g_mbps : NATURAL; g_mbps : NATURAL; -- line rate in Mbps so including 10/8 encoding
g_tx : BOOLEAN; g_tx : BOOLEAN;
g_rx : BOOLEAN g_rx : BOOLEAN
); );
...@@ -65,11 +65,12 @@ END sim_transceiver_gx; ...@@ -65,11 +65,12 @@ END sim_transceiver_gx;
ARCHITECTURE str OF sim_transceiver_gx IS 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); 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 tr_rst : STD_LOGIC;
SIGNAL i_tx_clk : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
SIGNAL tx_ready : STD_LOGIC; SIGNAL tx_ready : STD_LOGIC;
SIGNAL tx_in_ctrl : t_ctrl_2arr; SIGNAL tx_in_ctrl : t_ctrl_2arr;
...@@ -77,7 +78,20 @@ ARCHITECTURE str OF sim_transceiver_gx IS ...@@ -77,7 +78,20 @@ ARCHITECTURE str OF sim_transceiver_gx IS
BEGIN 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 p_tx_rdy : PROCESS
VARIABLE v_tx_clk_cnt : NATURAL := 0; VARIABLE v_tx_clk_cnt : NATURAL := 0;
...@@ -85,7 +99,7 @@ BEGIN ...@@ -85,7 +99,7 @@ BEGIN
tx_ready <= '0'; tx_ready <= '0';
WAIT FOR 1084.8 ns; -- Time until tx_rst (in tr_clk domain) is deasserted: tx init done 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 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; v_tx_clk_cnt := v_tx_clk_cnt + 1;
tx_ready <= '1'; tx_ready <= '1';
END LOOP; END LOOP;
...@@ -97,14 +111,12 @@ BEGIN ...@@ -97,14 +111,12 @@ BEGIN
tx_siso_arr(i).ready <= tx_ready; tx_siso_arr(i).ready <= tx_ready;
tx_siso_arr(i).xon <= 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) <= (OTHERS=>tx_sosi_arr(i).valid);
tx_in_ctrl(i)(j) <= tx_sosi_arr(i).valid;
END GENERATE;
u_ser: ENTITY work.sim_transceiver_serializer u_ser: ENTITY work.sim_transceiver_serializer
GENERIC MAP ( GENERIC MAP (
g_data_w => g_data_w, g_data_w => g_data_w,
g_line_rate => g_mbps g_tr_clk_period => c_tr_clk_period
) )
PORT MAP ( PORT MAP (
tb_end => tb_end, tb_end => tb_end,
...@@ -112,13 +124,10 @@ BEGIN ...@@ -112,13 +124,10 @@ BEGIN
tr_clk => tr_clk, tr_clk => tr_clk,
tr_rst => tr_rst, 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_data => tx_sosi_arr(i).data(g_data_w-1 DOWNTO 0),
tx_in_ctrl => tx_in_ctrl(i), tx_in_ctrl => tx_in_ctrl(i),
tx_out => tx_dataout(i) tx_serial_out => tx_dataout(i)
); );
END GENERATE; END GENERATE;
...@@ -126,7 +135,7 @@ BEGIN ...@@ -126,7 +135,7 @@ BEGIN
u_des: ENTITY work.sim_transceiver_deserializer u_des: ENTITY work.sim_transceiver_deserializer
GENERIC MAP ( GENERIC MAP (
g_data_w => g_data_w, g_data_w => g_data_w,
g_line_rate => g_mbps g_tr_clk_period => c_tr_clk_period
) )
PORT MAP ( PORT MAP (
tb_end => tb_end, tb_end => tb_end,
...@@ -134,13 +143,10 @@ BEGIN ...@@ -134,13 +143,10 @@ BEGIN
tr_clk => tr_clk, tr_clk => tr_clk,
tr_rst => tr_rst, 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_data => rx_sosi_arr(i).data(g_data_w-1 DOWNTO 0),
rx_out_ctrl => rx_out_ctrl(i), rx_out_ctrl => rx_out_ctrl(i),
rx_in => rx_datain(i) rx_serial_in => rx_datain(i)
); );
END GENERATE; END GENERATE;
...@@ -148,15 +154,5 @@ BEGIN ...@@ -148,15 +154,5 @@ BEGIN
END GENERATE; 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; END str;
...@@ -23,40 +23,48 @@ ...@@ -23,40 +23,48 @@
-- Purpose: -- Purpose:
-- Basic serializer model for fast transceiver simulation -- Basic serializer model for fast transceiver simulation
-- Description: -- Description:
-- This model can be connected to the transmitter entity serial -- The model serializes parallel data using 10 serial bits per byte. The two
-- transmitter output in simulation. As all serializers in the simualation are -- 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 -- simultaneously released from reset and share the same transceiver
-- reference clock, we don't need to worry about synchronization and can -- 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 -- simply assign one or more bits per serial group as validity indicator. The
-- straightforward is to mimic 10/8 encoding for as far as data rates and clock -- most straightforward is to mimic 10/8 encoding for as far as data rates
-- ratios are concerned (not the encoding itself): -- and clock ratios are concerned (not the encoding itself):
-- * User data rate = (8/10)*line data rate -- * User data rate = (8/10)*line data rate
-- * User clock frequency = User data rate / user data width -- * User clock frequency = User data rate / user data width
-- * Serial data block size = 10 bits [9..0] LSb sent first -- * 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. -- * [8] = Control bit.
-- * [7..0] = Data -- * [7..0] = Data
-- * Word/byte alignment is not required because reference clk and rst are global in -- * Word/byte alignment is not required because reference clk and rst are
-- simulation: what gets transmitted first is received first. -- 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 -- The following diagram shows the serialization of the 32-bit word 0x2. The
-- indicates the bit resolution. Note the 1 serial cycle of delay before the first bit -- grid of dots indicates the bit resolution. Note the 1 serial cycle of delay
-- is put on the line. -- before the first bit is put on the line.
-- --
-- . _______________________________________ . . . . . . . . . . . . . . . . . . . . . -- . _______________________________________ . . . . . . . . . . . . . . . . . . . . .
-- tx_clk _|. . . . . . . . . . . . . . . . . . . .|_________________________________________ -- tr_clk _|. . . . . . . . . . . . . . . . . . . .|_________________________________________
-- _ . . _ . . . . . . _ . . . . . . . . . _ . . . . . . . . . _ . . . . . . . . . _ . -- _ . . _ . . . . . . _ . . . . . . . . . _ . . . . . . . . . _ . . . . . . . . . _ .
-- tx_out .|___|.|___________|.|_________________|.|_________________|.|_________________|.|_ -- 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 -- 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 ---->| -- |<----- Byte 0 ---->|<----- Byte 1 ---->|<----- Byte 2 ---->|<----- Byte 3 ---->|
-- --
-- Remarks: -- Remarks:
-- . Requirements:
-- . All serializers in the simualation should be simultaneously released from -- . All serializers in the simualation should be simultaneously released from
-- reset and have to share the same transceiver reference clock. -- reset and have to share the same transceiver reference clock.
-- . This serializer is used in the tr_nonbonded module as a behavioural model -- . The number of line clock cycles to transmit one data word fits within 1
-- inside phy_gx.vhd. -- tr_clk period. After every data word the data is realigned to the tr_clk.
LIBRARY IEEE, common_lib; LIBRARY IEEE, common_lib;
...@@ -67,21 +75,18 @@ USE common_lib.common_pkg.ALL; ...@@ -67,21 +75,18 @@ USE common_lib.common_pkg.ALL;
ENTITY sim_transceiver_serializer IS ENTITY sim_transceiver_serializer IS
GENERIC( GENERIC(
g_data_w : NATURAL := 32; 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_tr_clk_period : TIME := 6.4 ns
); );
PORT( 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_clk : IN STD_LOGIC;
tr_rst : 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_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_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; END sim_transceiver_serializer;
...@@ -89,52 +94,46 @@ END sim_transceiver_serializer; ...@@ -89,52 +94,46 @@ END sim_transceiver_serializer;
ARCHITECTURE beh OF sim_transceiver_serializer IS 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_line_clk_period : TIME := g_tr_clk_period * 8 / 10 / g_data_w;
CONSTANT c_usr_nof_bytes : NATURAL := g_data_w / c_byte_w; CONSTANT c_tr_clk_period_sim : TIME := c_line_clk_period * g_data_w * 10 / 8;
CONSTANT c_tx_clk_per : TIME := c_line_clk_per * ( (g_data_w*10)/8 );
SIGNAL i_tx_clk : STD_LOGIC := '1'; CONSTANT c_nof_bytes_per_data : NATURAL := g_data_w / c_byte_w;
SIGNAL i_tx_rst : STD_LOGIC := '1';
BEGIN 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 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 BEGIN
tx_out <= '0'; tx_serial_out <= '0';
WAIT UNTIL tr_rst='0'; WAIT UNTIL tr_rst='0';
WAIT UNTIL i_tx_rst = '0' ;
-- Deserializer waits for c_line_clk_per/2 -- Align to tr_clk
WAIT FOR c_line_clk_per; 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 WHILE tb_end='0' LOOP
-- New serialization cycle -- Data word serialization cycle
FOR byte IN 0 TO c_usr_nof_bytes-1 LOOP FOR byte IN 0 TO c_nof_bytes_per_data-1 LOOP
-- Put a data byte on the line -- Serialize each data byte using 10 bits per byte on the line
FOR bit IN 0 TO c_byte_w-1 LOOP FOR bit IN 0 TO c_byte_w-1 LOOP
-- Put a data bit on the line tx_serial_out <= v_tx_in_data(byte*c_byte_w+bit); -- Put the 8 data bits of the data byte on the line
tx_out <= tx_in_data(byte*c_byte_w+bit); WAIT FOR c_line_clk_period;
-- 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;
END LOOP; END LOOP;
-- Put the control bit on the line for each byte tx_serial_out <= v_tx_in_ctrl(byte); -- Put the 1 control bit on the line for each byte
tx_out <= tx_in_ctrl(byte); WAIT FOR c_line_clk_period;
-- Wait for one line clk period tx_serial_out <= '0'; -- Put the 1 unused tenth bit = '0' on the line
WAIT FOR c_line_clk_per; IF byte<c_nof_bytes_per_data-1 THEN
-- Put the unused tenth bit = '0' on the line WAIT FOR c_line_clk_period; -- exit loop in last line clock cycle
tx_out <= '0'; END IF;
-- Wait for one line clk period
WAIT FOR c_line_clk_per;
END LOOP; 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 LOOP;
END PROCESS; END PROCESS;
......
...@@ -25,10 +25,10 @@ ...@@ -25,10 +25,10 @@
-- Description: -- Description:
-- Data generator -> Serializer -> Deserializer -> Data verification -- Data generator -> Serializer -> Deserializer -> Data verification
-- Usage: -- Usage:
-- as x -- as 10
-- run 2200 ns -- run -all
-- Observe: -- 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 -- . serial_line carries 4 bytes per serialized word. Each
-- byte is followed by its 2 valid bits and is sent LSb first. -- byte is followed by its 2 valid bits and is sent LSb first.
...@@ -43,104 +43,99 @@ END ENTITY tb_sim_transceiver_serdes; ...@@ -43,104 +43,99 @@ END ENTITY tb_sim_transceiver_serdes;
ARCHITECTURE tb of tb_sim_transceiver_serdes IS ARCHITECTURE tb of tb_sim_transceiver_serdes IS
CONSTANT c_tr_clk_period : TIME := 6.4 ns; -- 156.25 MHz
CONSTANT c_data_w : NATURAL := 32; CONSTANT c_data_w : NATURAL := 32;
CONSTANT c_line_rate : NATURAL := 6250; CONSTANT c_tr_clk_period : TIME := 6.4 ns; -- 156.25 MHz
SIGNAL enable : STD_LOGIC := '1'; SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL ready : STD_LOGIC;
SIGNAL tr_clk : STD_LOGIC := '0'; SIGNAL tr_clk : STD_LOGIC := '0';
SIGNAL tr_rst : STD_LOGIC := '1'; SIGNAL tr_rst : STD_LOGIC := '1';
SIGNAL tx_in : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0); SIGNAL tx_enable : STD_LOGIC := '1';
SIGNAL tx_ready : STD_LOGIC;
SIGNAL tx_in_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
SIGNAL tx_in_val : STD_LOGIC; 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_ctrl : STD_LOGIC_VECTOR(c_data_w/c_byte_w-1 DOWNTO 0);
SIGNAL tx_clk : STD_LOGIC;
SIGNAL tx_rst : STD_LOGIC;
SIGNAL serial_line : STD_LOGIC; SIGNAL serial_line : STD_LOGIC;
SIGNAL rx_clk : STD_LOGIC; SIGNAL rx_out_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
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_val : STD_LOGIC;
SIGNAL rx_out_ctrl : STD_LOGIC_VECTOR(c_data_w/c_byte_w-1 DOWNTO 0); 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 verify_en : STD_LOGIC := '0';
SIGNAL rd_ready : STD_LOGIC; SIGNAL rd_ready : STD_LOGIC := '1';
SIGNAL prev_rx_out : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
BEGIN
p_tb_end : PROCESS
BEGIN BEGIN
WAIT FOR c_tr_clk_period*300;
tr_clk <= NOT tr_clk AFTER c_tr_clk_period/2; -- 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; tr_rst <= '0' AFTER c_tr_clk_period*10;
p_ready: PROCESS p_tx_ready: PROCESS
BEGIN BEGIN
ready <= '0'; tx_ready <= '0';
WAIT UNTIL tx_rst = '0'; WAIT UNTIL tr_rst = '0';
WHILE TRUE LOOP WHILE tb_end='0' LOOP
ready <= '1'; tx_ready <= '1';
WAIT FOR c_tr_clk_period*50; WAIT FOR c_tr_clk_period*50;
ready <= '0'; tx_ready <= '0';
WAIT FOR c_tr_clk_period*50; WAIT FOR c_tr_clk_period*50;
END LOOP; END LOOP;
END PROCESS; END PROCESS;
-- Model FIFO output with c_rl = 1 and counter data starting at 0 -- Generate Tx data 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); 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 <= (OTHERS=>tx_in_val);
tx_in_ctrl(i) <= tx_in_val;
END GENERATE;
u_ser: ENTITY work.sim_transceiver_serializer u_ser: ENTITY work.sim_transceiver_serializer
GENERIC MAP ( GENERIC MAP (
g_data_w => c_data_w, g_data_w => c_data_w,
g_line_rate => c_line_rate g_tr_clk_period => c_tr_clk_period
) )
PORT MAP ( PORT MAP (
tb_end => tb_end,
tr_clk => tr_clk, tr_clk => tr_clk,
tr_rst => tr_rst, tr_rst => tr_rst,
tx_clk => tx_clk, tx_in_data => tx_in_data,
tx_rst => tx_rst,
tx_in_data => tx_in,
tx_in_ctrl => tx_in_ctrl, tx_in_ctrl => tx_in_ctrl,
tx_out => serial_line tx_serial_out => serial_line
); );
u_des: ENTITY work.sim_transceiver_deserializer u_des: ENTITY work.sim_transceiver_deserializer
GENERIC MAP ( GENERIC MAP (
g_data_w => c_data_w, g_data_w => c_data_w,
g_line_rate => c_line_rate g_tr_clk_period => c_tr_clk_period
) )
PORT MAP ( PORT MAP (
tb_end => tb_end,
tr_clk => tr_clk, tr_clk => tr_clk,
tr_rst => tr_rst, tr_rst => tr_rst,
rx_clk => rx_clk, rx_out_data => rx_out_data,
rx_rst => rx_rst,
rx_out_data => rx_out,
rx_out_ctrl => rx_out_ctrl, rx_out_ctrl => rx_out_ctrl,
rx_in => serial_line rx_serial_in => serial_line
); );
p_verify_en: PROCESS p_verify_en: PROCESS
BEGIN BEGIN
verify_en <= '0'; verify_en <= '0';
WAIT UNTIL rx_rst = '0'; WAIT UNTIL tr_rst = '0';
WAIT FOR c_tr_clk_period*5; WAIT FOR c_tr_clk_period*5;
verify_en <= '1'; verify_en <= '1';
WAIT; WAIT;
...@@ -149,6 +144,6 @@ BEGIN ...@@ -149,6 +144,6 @@ BEGIN
rx_out_val <= andv(rx_out_ctrl); rx_out_val <= andv(rx_out_ctrl);
-- Verify dut output incrementing data -- 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; END tb;
...@@ -76,9 +76,10 @@ END sim_xaui; ...@@ -76,9 +76,10 @@ END sim_xaui;
ARCHITECTURE wrap OF sim_xaui IS 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_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_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): -- XGMII control bits (one for each XGMII lane):
SIGNAL xgmii_tx_c_arr : t_xgmii_c_arr(g_nof_xaui-1 DOWNTO 0); SIGNAL xgmii_tx_c_arr : t_xgmii_c_arr(g_nof_xaui-1 DOWNTO 0);
...@@ -145,7 +146,7 @@ BEGIN ...@@ -145,7 +146,7 @@ BEGIN
u_ser: ENTITY tech_transceiver_lib.sim_transceiver_serializer u_ser: ENTITY tech_transceiver_lib.sim_transceiver_serializer
GENERIC MAP ( GENERIC MAP (
g_data_w => c_xaui_serdes_data_w, g_data_w => c_xaui_serdes_data_w,
g_line_rate => c_xaui_serdes_line_rate g_tr_clk_period => c_tr_clk_period
) )
PORT MAP ( PORT MAP (
tr_clk => tr_clk, tr_clk => tr_clk,
...@@ -154,13 +155,13 @@ BEGIN ...@@ -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_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_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 u_des: ENTITY tech_transceiver_lib.sim_transceiver_deserializer
GENERIC MAP ( GENERIC MAP (
g_data_w => c_xaui_serdes_data_w, g_data_w => c_xaui_serdes_data_w,
g_line_rate => c_xaui_serdes_line_rate g_tr_clk_period => c_tr_clk_period
) )
PORT MAP ( PORT MAP (
tr_clk => tr_clk, tr_clk => tr_clk,
...@@ -169,7 +170,7 @@ BEGIN ...@@ -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_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_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; END GENERATE;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment