OpenCores
URL https://opencores.org/ocsvn/astron_sim_transceiver/astron_sim_transceiver/trunk

Subversion Repositories astron_sim_transceiver

[/] [astron_sim_transceiver/] [trunk/] [sim_transceiver_serializer.vhd] - Rev 2

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
--
-- Copyright 2020
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
-- 
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
-- 
--     http://www.apache.org/licenses/LICENSE-2.0
-- 
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
 
-- Author:
-- . Daniel van der Schuur
-- Purpose:
--   Basic serializer model for fast transceiver simulation
-- Description:
--   The model serializes parallel data using 10 serial bits per byte. The two 
--   extra bits are used to transfer control (valid, SOP/EOP).
--   The model can represent any real transceiver encoding scheme (10b/8b, 66b/64b) 
--   because 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 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] = SOP/EOP; '1'=SOP;'U'=EOP.
--     *  [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.
--   
--  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.
--
--               . _______________________________________ . . . . . . . . . . . . . . . . . . . . .
-- tr_clk        _|. . . . . . . . . . . . . . . . . . . .|_________________________________________
--               _ . . _ . . . . . . _ . . . . . . . . . _ . . . . . . . . . _ . . . . . . . . . _ .        
-- tx_serial_out .|___|.|___________|.|_________________|.|_________________|.|_________________|.|_
--              
--               c P 0 1 2 3 4 5 6 7 c P 0 1 2 3 4 5 6 7 c P 0 1 2 3 4 5 6 7 c P 0 1 2 3 4 5 6 7 c P
--                  |<----- Byte 0 ---->|<----- Byte 1 ---->|<----- Byte 2 ---->|<----- Byte 3 ---->|
--
-- Remarks:
-- . 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_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE common_pkg_lib.common_pkg.ALL;
 
ENTITY sim_transceiver_serializer IS 
  GENERIC(
    g_data_w         : NATURAL := 32;
    g_tr_clk_period  : TIME := 6.4 ns
  );      
  PORT(
    tb_end        : IN  STD_LOGIC := '0';
 
    tr_clk        : IN  STD_LOGIC;
    tr_rst        : IN  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); -- 1 valid bit per byte
    tx_in_sop     : IN  STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0) := (OTHERS=>'0'); -- 1 SOP   bit per byte
    tx_in_eop     : IN  STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0) := (OTHERS=>'0'); -- 1 EOP   bit per byte
 
    tx_serial_out : OUT STD_LOGIC
  );
 
END sim_transceiver_serializer;
 
 
ARCHITECTURE beh OF sim_transceiver_serializer IS
 
  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;
 
  CONSTANT c_nof_bytes_per_data : NATURAL := g_data_w / c_byte_w;
 
BEGIN
 
  p_serialize: PROCESS
    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);
    VARIABLE v_tx_in_sop  : STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0);
    VARIABLE v_tx_in_eop  : STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0);
  BEGIN
    tx_serial_out <= '0';
    WAIT UNTIL tr_rst='0';
 
    -- Align to tr_clk
    WAIT UNTIL rising_edge(tr_clk);
    v_tx_in_data := tx_in_data;
    v_tx_in_ctrl := tx_in_ctrl;
    v_tx_in_sop  := tx_in_sop;
    v_tx_in_eop  := tx_in_eop;
 
    WHILE tb_end='0' LOOP
      -- 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
          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;
        tx_serial_out <= v_tx_in_ctrl(byte);                  -- Put the valid bit on the line for each byte
        WAIT FOR c_line_clk_period;
        tx_serial_out <= '0';                                 -- Put the SOP/EOP indicator bit on the line. '1'=SOP; 'U'=EOP.
        IF v_tx_in_sop(byte) = '1' THEN
          tx_serial_out <= '1';
        ELSIF v_tx_in_eop(byte)='1' THEN
          tx_serial_out <= 'U';
        END IF;
        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;
      v_tx_in_sop  := tx_in_sop;
      v_tx_in_eop  := tx_in_eop;
 
    END LOOP;
 
  END PROCESS;
 
END beh;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.