-- Copyright (c)2020 Jeremy Seth Henry
|
-- Copyright (c)2020 Jeremy Seth Henry
|
-- All rights reserved.
|
-- All rights reserved.
|
--
|
--
|
-- Redistribution and use in source and binary forms, with or without
|
-- Redistribution and use in source and binary forms, with or without
|
-- modification, are permitted provided that the following conditions are met:
|
-- modification, are permitted provided that the following conditions are met:
|
-- * Redistributions of source code must retain the above copyright
|
-- * Redistributions of source code must retain the above copyright
|
-- notice, this list of conditions and the following disclaimer.
|
-- notice, this list of conditions and the following disclaimer.
|
-- * Redistributions in binary form must reproduce the above copyright
|
-- * Redistributions in binary form must reproduce the above copyright
|
-- notice, this list of conditions and the following disclaimer in the
|
-- notice, this list of conditions and the following disclaimer in the
|
-- documentation and/or other materials provided with the distribution,
|
-- documentation and/or other materials provided with the distribution,
|
-- where applicable (as part of a user interface, debugging port, etc.)
|
-- where applicable (as part of a user interface, debugging port, etc.)
|
--
|
--
|
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
|
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
|
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
|
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
|
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
--
|
--
|
-- VHDL Units : o8_sdlc_if
|
-- VHDL Units : o8_sdlc_if
|
-- Description: Provides a full memory-mapped SDLC stack with automatic CRC16
|
-- Description: Provides a full memory-mapped SDLC stack with automatic CRC16
|
-- Checksum insertion and integrity checking.
|
-- Checksum insertion and integrity checking.
|
--
|
--
|
-- Transmit Memory Map
|
-- Transmit Memory Map
|
-- "0_0000_0000" (0x000) TX Buffer START
|
-- "0_0000_0000" (0x000) TX Buffer START
|
-- "0_1111_1101" (0x0FD) TX Buffer END
|
-- "0_1111_1101" (0x0FD) TX Buffer END
|
-- "0_1111_1110" (0x0FE) Clock Status*
|
-- "0_1111_1110" (0x0FE) Clock Status*
|
-- "0_1111_1111" (0x0FF) TX Length / Status**
|
-- "0_1111_1111" (0x0FF) TX Length / Status**
|
--
|
--
|
-- Receive Memory Map
|
-- Receive Memory Map
|
-- "1_0000_0000" (0x100) RX Buffer START
|
-- "1_0000_0000" (0x100) RX Buffer START
|
-- "1_1111_1101" (0x1FD) RX Buffer END
|
-- "1_1111_1101" (0x1FD) RX Buffer END
|
-- "1_1111_1110" (0x0FE) RX Checksum Status***
|
-- "1_1111_1110" (0x0FE) RX Checksum Status***
|
-- "1_1111_1111" (0x1FF) RX Length Status****
|
-- "1_1111_1111" (0x1FF) RX Length Status****
|
--
|
--
|
-- * Address 0xFE reports the SDLC bit clock status and updates on changes.
|
-- * Address 0xFE reports the SDLC bit clock status and updates on changes.
|
-- 1) If BClk_Okay = '0' (Bitclock is NOT present), the field will report
|
-- 1) If BClk_Okay = '0' (Bitclock is NOT present), the field will report
|
-- 0x00. Otherwise, it will report 0xFF if the bitclock is present.
|
-- 0x00. Otherwise, it will report 0xFF if the bitclock is present.
|
-- 2) Writing any value to the register will cause the controller to
|
-- 2) Writing any value to the register will cause the controller to
|
-- silently reset the clock status without causing an interrupt.
|
-- silently reset the clock status without causing an interrupt.
|
--
|
--
|
-- ** This location serves as the control/status register for transmit
|
-- ** This location serves as the control/status register for transmit
|
-- 1) Writing a value between 1 and 253 will trigger the transmit engine,
|
-- 1) Writing a value between 1 and 253 will trigger the transmit engine,
|
-- using the write value as the packet length.
|
-- using the write value as the packet length.
|
-- 2) Values 0x00, 0xFE, or 0xFF are invalid, and will be ignored.
|
-- 2) Values 0x00, 0xFE, or 0xFF are invalid, and will be ignored.
|
-- 3) This value will change from the user written value to 0xFF once the
|
-- 3) This value will change from the user written value to 0xFF once the
|
-- packet is transmitted to indicate the transmission is complete.
|
-- packet is transmitted to indicate the transmission is complete.
|
--
|
--
|
-- *** This location serves as the status register for receive checksum test
|
-- *** This location serves as the status register for receive checksum test
|
-- 1) A value of 0x00 indicates the CRC did NOT match, while a value
|
-- 1) A value of 0x00 indicates the CRC did NOT match, while a value
|
-- of 0xFF indicates that the recieved CRC matches the calculated CRC.
|
-- of 0xFF indicates that the recieved CRC matches the calculated CRC.
|
--
|
--
|
-- **** This location serves as the status register for the receive
|
-- **** This location serves as the status register for the receive
|
-- 1) This value is only updated on reception of a full frame, indicated
|
-- 1) This value is only updated on reception of a full frame, indicated
|
-- by a start followed by a stop flag. Incomplete frames are ignored.
|
-- by a start followed by a stop flag. Incomplete frames are ignored.
|
-- 2) If the packet CRC matches the transmitted CRC, the packet is
|
-- 2) If the packet CRC matches the transmitted CRC, the packet is
|
-- considered valid, and the received length (less CRC) is written.
|
-- considered valid, and the received length (less CRC) is written.
|
-- 3) If the packet CRC doesn't match, a value of ERR_CHECKSUM is written.
|
-- 3) If the packet CRC doesn't match, a value of ERR_CHECKSUM is written.
|
-- 4) If too many bytes are received (buffer overflow), a value of
|
-- 4) If too many bytes are received (buffer overflow), a value of
|
-- ERR_LENGTH is written.
|
-- ERR_LENGTH is written.
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_arith.all;
|
|
|
library work;
|
library work;
|
use work.open8_pkg.all;
|
use work.open8_pkg.all;
|
|
|
library work;
|
library work;
|
use work.sdlc_serial_pkg.all;
|
use work.sdlc_serial_pkg.all;
|
|
|
entity o8_sdlc_if is
|
entity o8_sdlc_if is
|
generic(
|
generic(
|
Monitor_Enable : boolean := true;
|
Monitor_Enable : boolean := false;
|
Attach_Monitor_to_CPU_Side : boolean := false;
|
Attach_Monitor_to_CPU_Side : boolean := false;
|
Poly_Init : std_logic_vector(15 downto 0) := x"0000";
|
Poly_Init : std_logic_vector(15 downto 0) := x"0000";
|
Set_As_Master : boolean := true;
|
Set_As_Master : boolean := true;
|
Clock_Offset : integer := 6;
|
Clock_Offset : integer := 6;
|
BitClock_Freq : real := 500000.0;
|
BitClock_Freq : real := 500000.0;
|
Sys_Freq : real := 100000000.0;
|
Sys_Freq : real := 100000000.0;
|
Reset_Level : std_logic := '1';
|
Reset_Level : std_logic := '1';
|
Address : ADDRESS_TYPE
|
Address : ADDRESS_TYPE
|
);
|
);
|
port(
|
port(
|
Clock : in std_logic;
|
Clock : in std_logic;
|
Reset : in std_logic;
|
Reset : in std_logic;
|
--
|
--
|
Bus_Address : in ADDRESS_TYPE;
|
Bus_Address : in ADDRESS_TYPE;
|
Wr_Enable : in std_logic;
|
Wr_Enable : in std_logic;
|
Wr_Data : in DATA_TYPE;
|
Wr_Data : in DATA_TYPE;
|
Rd_Enable : in std_logic;
|
Rd_Enable : in std_logic;
|
Rd_Data : out DATA_TYPE;
|
Rd_Data : out DATA_TYPE;
|
Interrupt : out std_logic;
|
Interrupt : out std_logic;
|
-- Serial IO
|
-- Serial IO
|
SDLC_In : in std_logic;
|
SDLC_In : in std_logic;
|
SDLC_SClk : in std_logic;
|
SDLC_SClk : in std_logic;
|
SDLC_MClk : out std_logic;
|
SDLC_MClk : out std_logic;
|
SDLC_Out : out std_logic
|
SDLC_Out : out std_logic
|
);
|
);
|
end entity;
|
end entity;
|
|
|
architecture behave of o8_sdlc_if is
|
architecture behave of o8_sdlc_if is
|
|
|
-- Connect the CPU to the dual-port memory
|
-- Connect the CPU to the dual-port memory
|
constant Base_Addr : std_logic_vector(15 downto 9)
|
constant Base_Addr : std_logic_vector(15 downto 9)
|
:= Address(15 downto 9);
|
:= Address(15 downto 9);
|
|
|
alias RAM_Upper_Addr is Bus_Address(15 downto 9);
|
alias RAM_Upper_Addr is Bus_Address(15 downto 9);
|
alias RAM_Lower_Addr is Bus_Address(8 downto 0);
|
alias RAM_Lower_Addr is Bus_Address(8 downto 0);
|
|
|
signal RAM_Addr_Match : std_logic := '0';
|
signal RAM_Addr_Match : std_logic := '0';
|
signal RAM_Wr_En : std_logic := '0';
|
signal RAM_Wr_En : std_logic := '0';
|
signal RAM_Rd_En : std_logic := '0';
|
signal RAM_Rd_En : std_logic := '0';
|
signal Rd_Data_i : DATA_TYPE := OPEN8_NULLBUS;
|
signal Rd_Data_i : DATA_TYPE := OPEN8_NULLBUS;
|
|
|
constant Reg_Sub_Addr : std_logic_vector(8 downto 1) := x"7F";
|
constant Reg_Sub_Addr : std_logic_vector(8 downto 1) := x"7F";
|
|
|
alias Reg_Upper_Addr is Bus_Address(8 downto 1);
|
alias Reg_Upper_Addr is Bus_Address(8 downto 1);
|
alias Reg_Lower_Addr is Bus_Address(0);
|
alias Reg_Lower_Addr is Bus_Address(0);
|
|
|
signal Reg_Addr : std_logic_vector(8 downto 1) := (others => '0');
|
signal Reg_Addr : std_logic_vector(8 downto 1) := (others => '0');
|
signal Reg_Sel : std_logic := '0';
|
signal Reg_Sel : std_logic := '0';
|
signal Reg_Wr_En : std_logic := '0';
|
signal Reg_Wr_En : std_logic := '0';
|
signal Reg_Clk_Sel : std_logic := '0';
|
signal Reg_Clk_Sel : std_logic := '0';
|
signal Reg_TxS_Sel : std_logic := '0';
|
signal Reg_TxS_Sel : std_logic := '0';
|
|
|
-- Connect the serial engine to the dual-port memory
|
|
signal DP_Addr : std_logic_vector(8 downto 0) := (others => '0');
|
signal DP_Addr : std_logic_vector(8 downto 0) := (others => '0');
|
signal DP_Wr_Data : DATA_IN_TYPE := x"00";
|
signal DP_Wr_Data : DATA_IN_TYPE := x"00";
|
signal DP_Wr_En : std_logic := '0';
|
signal DP_Wr_En : std_logic := '0';
|
signal DP_Rd_Data : DATA_IN_TYPE := x"00";
|
signal DP_Rd_Data : DATA_IN_TYPE := x"00";
|
|
|
|
signal DP_Port0_Addr : DATA_IN_TYPE := x"00";
|
|
signal DP_Port0_RWn : std_logic := '0';
|
|
signal DP_Port0_WrData : DATA_IN_TYPE := x"00";
|
|
signal DP_Port0_RdData : DATA_IN_TYPE := x"00";
|
|
signal DP_Port0_Req : std_logic := '0';
|
|
signal DP_Port0_Ack : std_logic := '0';
|
|
|
|
signal DP_Port1_Addr : DATA_IN_TYPE := x"00";
|
|
signal DP_Port1_RWn : std_logic := '0';
|
|
signal DP_Port1_WrData : DATA_IN_TYPE := x"00";
|
|
signal DP_Port1_RdData : DATA_IN_TYPE := x"00";
|
|
signal DP_Port1_Req : std_logic := '0';
|
|
signal DP_Port1_Ack : std_logic := '0';
|
|
|
signal BClk_RE : std_logic := '0';
|
signal BClk_RE : std_logic := '0';
|
signal BClk_FE : std_logic := '0';
|
signal BClk_FE : std_logic := '0';
|
|
signal BClk_Okay : std_logic := '0';
|
|
|
signal TX_Wr_En : std_logic := '0';
|
signal TX_Wr_En : std_logic := '0';
|
signal TX_Wr_Flag : std_logic := '0';
|
signal TX_Wr_Flag : std_logic := '0';
|
signal TX_Wr_Data : DATA_IN_TYPE := x"00";
|
signal TX_Wr_Data : DATA_IN_TYPE := x"00";
|
signal TX_Req_Next : std_logic := '0';
|
signal TX_Req_Next : std_logic := '0';
|
|
|
signal TX_CRC_Clr : std_logic := '0';
|
signal TX_CRC_Clr : std_logic := '0';
|
signal TX_CRC_En : std_logic := '0';
|
signal TX_CRC_En : std_logic := '0';
|
signal TX_CRC_Data : CRC_OUT_TYPE := x"0000";
|
signal TX_CRC_Data : CRC_OUT_TYPE := x"0000";
|
alias TX_CRC_Data_LB is TX_CRC_Data(7 downto 0);
|
|
alias TX_CRC_Data_UB is TX_CRC_Data(15 downto 8);
|
|
signal TX_CRC_Valid : std_logic := '0';
|
signal TX_CRC_Valid : std_logic := '0';
|
|
|
|
signal TX_Interrupt : std_logic := '0';
|
|
|
signal RX_Valid : std_logic := '0';
|
signal RX_Valid : std_logic := '0';
|
signal RX_Flag : std_logic := '0';
|
signal RX_Flag : std_logic := '0';
|
signal RX_Data : DATA_IN_TYPE := x"00";
|
signal RX_Data : DATA_IN_TYPE;
|
signal RX_Idle : std_logic := '0';
|
signal RX_Idle : std_logic := '0';
|
|
|
signal RX_CRC_Clr : std_logic := '0';
|
signal RX_Frame_Start : std_logic := '0';
|
signal RX_CRC_En : std_logic := '0';
|
signal RX_Frame_Stop : std_logic := '0';
|
signal RX_CRC_Data : CRC_OUT_TYPE := x"0000";
|
signal RX_Frame_Valid : std_logic := '0';
|
|
signal RX_Frame_Data : DATA_IN_TYPE := x"00";
|
|
|
signal RX_CRC_Valid : std_logic := '0';
|
signal RX_CRC_Valid : std_logic := '0';
|
|
signal RX_CRC_Data : CRC_OUT_TYPE := x"0000";
|
|
|
signal BClk_Okay : std_logic := '0';
|
signal RX_Interrupt : std_logic := '0';
|
|
|
begin
|
begin
|
|
|
|
-- ***************************************************************************
|
|
-- * Open8 Bus Interface and Control Register Detection *
|
|
-- ***************************************************************************
|
|
|
-- This decode needs to happen immediately, to give the RAM a chance to
|
-- This decode needs to happen immediately, to give the RAM a chance to
|
-- do the lookup before we have to set Rd_Data
|
-- do the lookup before we have to set Rd_Data
|
RAM_Addr_Match <= '1' when Base_Addr = RAM_Upper_Addr else '0';
|
RAM_Addr_Match <= '1' when Base_Addr = RAM_Upper_Addr else '0';
|
RAM_Wr_En <= RAM_Addr_Match and Wr_Enable;
|
RAM_Wr_En <= RAM_Addr_Match and Wr_Enable;
|
|
|
CPU_RAM_proc: process( Reset, Clock )
|
CPU_RAM_proc: process( Reset, Clock )
|
begin
|
begin
|
if( Reset = Reset_Level )then
|
if( Reset = Reset_Level )then
|
Reg_Addr <= (others => '0');
|
Reg_Addr <= (others => '0');
|
Reg_Wr_En <= '0';
|
Reg_Wr_En <= '0';
|
Reg_Clk_Sel <= '0';
|
Reg_Clk_Sel <= '0';
|
Reg_TxS_Sel <= '0';
|
Reg_TxS_Sel <= '0';
|
RAM_Rd_En <= '0';
|
RAM_Rd_En <= '0';
|
Rd_Data <= OPEN8_NULLBUS;
|
Rd_Data <= OPEN8_NULLBUS;
|
elsif( rising_edge(Clock) )then
|
elsif( rising_edge(Clock) )then
|
Reg_Addr <= Reg_Upper_Addr;
|
Reg_Addr <= Reg_Upper_Addr;
|
Reg_Sel <= Reg_Lower_Addr;
|
Reg_Sel <= Reg_Lower_Addr;
|
Reg_Wr_En <= RAM_Addr_Match and Wr_Enable;
|
Reg_Wr_En <= RAM_Addr_Match and Wr_Enable;
|
|
|
Reg_Clk_Sel <= '0';
|
Reg_Clk_Sel <= '0';
|
Reg_TxS_Sel <= '0';
|
Reg_TxS_Sel <= '0';
|
if( Reg_Addr = Reg_Sub_Addr )then
|
if( Reg_Addr = Reg_Sub_Addr )then
|
Reg_Clk_Sel <= Reg_Wr_En and not Reg_Sel;
|
Reg_Clk_Sel <= Reg_Wr_En and not Reg_Sel;
|
Reg_TxS_Sel <= Reg_Wr_En and Reg_Sel;
|
Reg_TxS_Sel <= Reg_Wr_En and Reg_Sel;
|
end if;
|
end if;
|
|
|
RAM_Rd_En <= RAM_Addr_Match and Rd_Enable;
|
RAM_Rd_En <= RAM_Addr_Match and Rd_Enable;
|
Rd_Data <= OPEN8_NULLBUS;
|
Rd_Data <= OPEN8_NULLBUS;
|
if( RAM_Rd_En = '1' )then
|
if( RAM_Rd_En = '1' )then
|
Rd_Data <= Rd_Data_i;
|
Rd_Data <= Rd_Data_i;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
|
-- ***************************************************************************
|
|
-- * Shared Dual-Port Memory *
|
|
-- ***************************************************************************
|
|
|
U_RAM : entity work.sdlc_dp512b_ram
|
U_RAM : entity work.sdlc_dp512b_ram
|
port map(
|
port map(
|
clock => Clock,
|
clock => Clock,
|
address_a => RAM_Lower_Addr,
|
address_a => RAM_Lower_Addr,
|
address_b => DP_Addr,
|
address_b => DP_Addr,
|
data_a => Wr_Data,
|
data_a => Wr_Data,
|
data_b => DP_Wr_Data,
|
data_b => DP_Wr_Data,
|
wren_a => RAM_Wr_En,
|
wren_a => RAM_Wr_En,
|
wren_b => DP_Wr_En,
|
wren_b => DP_Wr_En,
|
q_a => Rd_Data_i,
|
q_a => Rd_Data_i,
|
q_b => DP_Rd_Data
|
q_b => DP_Rd_Data
|
);
|
);
|
|
|
Attach_to_CPU_side: if( Monitor_Enable and Attach_Monitor_to_CPU_Side )generate
|
Attach_to_CPU_side: if( Monitor_Enable and Attach_Monitor_to_CPU_Side )generate
|
|
|
U_MON: entity work.sdlc_monitor
|
U_MON: entity work.sdlc_monitor
|
port map(
|
port map(
|
clock => Clock,
|
clock => Clock,
|
address => RAM_Lower_Addr,
|
address => RAM_Lower_Addr,
|
data => Wr_Data,
|
data => Wr_Data,
|
wren => RAM_Wr_En,
|
wren => RAM_Wr_En,
|
q => open
|
q => open
|
);
|
);
|
end generate;
|
end generate;
|
|
|
Attach_to_Int_side: if( Monitor_Enable and not Attach_Monitor_to_CPU_Side )generate
|
Attach_to_Int_side: if( Monitor_Enable and not Attach_Monitor_to_CPU_Side )generate
|
|
|
U_MON: entity work.sdlc_monitor
|
U_MON: entity work.sdlc_monitor
|
port map(
|
port map(
|
clock => Clock,
|
clock => Clock,
|
address => DP_Addr,
|
address => DP_Addr,
|
data => DP_Wr_Data,
|
data => DP_Wr_Data,
|
wren => DP_Wr_En,
|
wren => DP_Wr_En,
|
q => open
|
q => open
|
);
|
);
|
|
|
end generate;
|
end generate;
|
|
|
|
-- ***************************************************************************
|
|
-- * Memory Arbitration *
|
|
-- ***************************************************************************
|
|
|
|
U_ARB : entity work.sdlc_serial_arbfsm
|
|
generic map(
|
|
Reset_Level => Reset_Level
|
|
)
|
|
port map(
|
|
Clock => Clock,
|
|
Reset => Reset,
|
|
--
|
|
DP_Port0_Addr => DP_Port0_Addr,
|
|
DP_Port0_RWn => DP_Port0_RWn,
|
|
DP_Port0_WrData => DP_Port0_WrData,
|
|
DP_Port0_RdData => DP_Port0_RdData,
|
|
DP_Port0_Req => DP_Port0_Req,
|
|
DP_Port0_Ack => DP_Port0_Ack,
|
|
--
|
|
DP_Port1_Addr => DP_Port1_Addr,
|
|
DP_Port1_RWn => DP_Port1_RWn,
|
|
DP_Port1_WrData => DP_Port1_WrData,
|
|
DP_Port1_RdData => DP_Port1_RdData,
|
|
DP_Port1_Req => DP_Port1_Req,
|
|
DP_Port1_Ack => DP_Port1_Ack,
|
|
--
|
|
DP_Addr => DP_Addr,
|
|
DP_Wr_Data => DP_Wr_Data,
|
|
DP_Wr_En => DP_Wr_En,
|
|
DP_Rd_Data => DP_Rd_Data
|
|
);
|
|
|
|
-- ***************************************************************************
|
|
-- * Serial BitClock *
|
|
-- ***************************************************************************
|
|
|
U_BCLK : entity work.sdlc_serial_clk
|
U_BCLK : entity work.sdlc_serial_clk
|
generic map(
|
generic map(
|
Set_As_Master => Set_As_Master,
|
Set_As_Master => Set_As_Master,
|
BitClock_Freq => BitClock_Freq,
|
BitClock_Freq => BitClock_Freq,
|
Reset_Level => Reset_Level,
|
Reset_Level => Reset_Level,
|
Sys_Freq => Sys_Freq
|
Sys_Freq => Sys_Freq
|
)
|
)
|
port map(
|
port map(
|
Clock => Clock,
|
Clock => Clock,
|
Reset => Reset,
|
Reset => Reset,
|
--
|
--
|
BClk_In => SDLC_SClk,
|
BClk_In => SDLC_SClk,
|
BClk_Out => SDLC_MClk,
|
BClk_Out => SDLC_MClk,
|
BClk_FE => BClk_FE,
|
BClk_FE => BClk_FE,
|
BClk_RE => BClk_RE,
|
BClk_RE => BClk_RE,
|
BClk_Okay => BClk_Okay
|
BClk_Okay => BClk_Okay
|
);
|
);
|
|
|
U_CTRL : entity work.sdlc_serial_ctrl
|
-- ***************************************************************************
|
|
-- * Serial Transmit Path *
|
|
-- ***************************************************************************
|
|
|
|
U_TXFSM: entity work.sdlc_serial_txfsm
|
generic map(
|
generic map(
|
Reset_Level => Reset_Level
|
Reset_Level => Reset_Level
|
)
|
)
|
port map(
|
port map(
|
Clock => Clock,
|
Clock => Clock,
|
Reset => Reset,
|
Reset => Reset,
|
--
|
--
|
BClk_Okay => BClk_Okay,
|
BClk_Okay => BClk_Okay,
|
--
|
--
|
Reg_Clk_Sel => Reg_Clk_Sel,
|
Reg_Clk_Sel => Reg_Clk_Sel,
|
Reg_TxS_Sel => Reg_TxS_Sel,
|
Reg_TxS_Sel => Reg_TxS_Sel,
|
--
|
--
|
DP_Addr => DP_Addr,
|
DP_Port0_Addr => DP_Port0_Addr,
|
DP_Wr_Data => DP_Wr_Data,
|
DP_Port0_RWn => DP_Port0_RWn,
|
DP_Wr_En => DP_Wr_En,
|
DP_Port0_WrData => DP_Port0_WrData,
|
DP_Rd_Data => DP_Rd_Data,
|
DP_Port0_RdData => DP_Port0_RdData,
|
|
DP_Port0_Req => DP_Port0_Req,
|
|
DP_Port0_Ack => DP_Port0_Ack,
|
--
|
--
|
TX_Wr_En => TX_Wr_En,
|
TX_Wr_En => TX_Wr_En,
|
TX_Wr_Flag => TX_Wr_Flag,
|
TX_Wr_Flag => TX_Wr_Flag,
|
TX_Wr_Data => TX_Wr_Data,
|
TX_Wr_Data => TX_Wr_Data,
|
TX_Req_Next => TX_Req_Next,
|
TX_Req_Next => TX_Req_Next,
|
--
|
--
|
TX_CRC_Clr => TX_CRC_Clr,
|
TX_CRC_Clr => TX_CRC_Clr,
|
TX_CRC_En => TX_CRC_En,
|
TX_CRC_En => TX_CRC_En,
|
TX_CRC_Data => TX_CRC_Data,
|
TX_CRC_Data => TX_CRC_Data,
|
TX_CRC_Valid => TX_CRC_Valid,
|
TX_CRC_Valid => TX_CRC_Valid,
|
--
|
--
|
RX_Valid => RX_Valid,
|
TX_Interrupt => TX_Interrupt
|
RX_Flag => RX_Flag,
|
);
|
RX_Data => RX_Data,
|
|
RX_Idle => RX_Idle,
|
U_TX_CRC : entity work.sdlc_crc16_ccitt
|
|
generic map(
|
|
Poly_Init => Poly_Init,
|
|
Reset_Level => Reset_Level
|
|
)
|
|
port map(
|
|
Clock => Clock,
|
|
Reset => Reset,
|
--
|
--
|
RX_CRC_Clr => RX_CRC_Clr,
|
Clear => TX_CRC_Clr,
|
RX_CRC_En => RX_CRC_En,
|
Wr_En => TX_CRC_En,
|
RX_CRC_Data => RX_CRC_Data,
|
Wr_Data => TX_Wr_Data,
|
RX_CRC_Valid => RX_CRC_Valid,
|
|
--
|
--
|
Interrupt => Interrupt
|
CRC16_Valid => TX_CRC_Valid,
|
|
CRC16_Out => TX_CRC_Data
|
);
|
);
|
|
|
U_TX_SER : entity work.sdlc_serial_tx
|
U_TX_SER : entity work.sdlc_serial_tx
|
generic map(
|
generic map(
|
Reset_Level => Reset_Level
|
Reset_Level => Reset_Level
|
)
|
)
|
port map(
|
port map(
|
Clock => Clock,
|
Clock => Clock,
|
Reset => Reset,
|
Reset => Reset,
|
--
|
--
|
BClk_FE => BClk_FE,
|
BClk_FE => BClk_FE,
|
BClk_RE => BClk_RE,
|
BClk_RE => BClk_RE,
|
BClk_Okay => BClk_Okay,
|
BClk_Okay => BClk_Okay,
|
--
|
--
|
TX_En => TX_Wr_En,
|
TX_En => TX_Wr_En,
|
TX_FSS_Flag => TX_Wr_Flag,
|
TX_FSS_Flag => TX_Wr_Flag,
|
TX_Data => TX_Wr_Data,
|
TX_Data => TX_Wr_Data,
|
TX_Req_Next => TX_Req_Next,
|
TX_Req_Next => TX_Req_Next,
|
--
|
--
|
Serial_Out => SDLC_Out
|
Serial_Out => SDLC_Out
|
);
|
);
|
|
|
U_TX_CRC : entity work.sdlc_crc16_ccitt
|
-- ***************************************************************************
|
generic map(
|
-- * Serial Receive Path *
|
Poly_Init => Poly_Init,
|
-- ***************************************************************************
|
Reset_Level => Reset_Level
|
|
)
|
|
port map(
|
|
Clock => Clock,
|
|
Reset => Reset,
|
|
--
|
|
Clear => TX_CRC_Clr,
|
|
Wr_Data => TX_Wr_Data,
|
|
Wr_En => TX_CRC_En,
|
|
--
|
|
CRC16_Out => TX_CRC_Data,
|
|
CRC16_Valid => TX_CRC_Valid
|
|
);
|
|
|
|
U_RX_SER : entity work.sdlc_serial_rx
|
U_RX_SER : entity work.sdlc_serial_rx
|
generic map(
|
generic map(
|
Set_As_Master => Set_As_Master,
|
Set_As_Master => Set_As_Master,
|
Clock_Offset => Clock_Offset,
|
Clock_Offset => Clock_Offset,
|
Reset_Level => Reset_Level
|
Reset_Level => Reset_Level
|
)
|
)
|
port map(
|
port map(
|
Clock => Clock,
|
Clock => Clock,
|
Reset => Reset,
|
Reset => Reset,
|
--
|
--
|
BClk_RE => BClk_RE,
|
BClk_RE => BClk_RE,
|
BClk_Okay => BClk_Okay,
|
BClk_Okay => BClk_Okay,
|
--
|
--
|
Serial_In => SDLC_In,
|
Serial_In => SDLC_In,
|
--
|
--
|
RX_Valid => RX_Valid,
|
RX_Valid => RX_Valid,
|
RX_Flag => RX_Flag,
|
RX_Flag => RX_Flag,
|
RX_Data => RX_Data,
|
RX_Data => RX_Data,
|
RX_Idle => RX_Idle
|
RX_Idle => RX_Idle
|
);
|
);
|
|
|
|
U_RX_PKT : entity work.sdlc_serial_frame
|
|
generic map(
|
|
Reset_Level => Reset_Level
|
|
)
|
|
port map(
|
|
Clock => Clock,
|
|
Reset => Reset,
|
|
--
|
|
RX_Valid => RX_Valid,
|
|
RX_Flag => RX_Flag,
|
|
RX_Data => RX_Data,
|
|
RX_Idle => RX_Idle,
|
|
--
|
|
RX_Frame_Start => RX_Frame_Start,
|
|
RX_Frame_Stop => RX_Frame_Stop,
|
|
RX_Frame_Valid => RX_Frame_Valid,
|
|
RX_Frame_Data => RX_Frame_Data
|
|
);
|
|
|
U_RX_CRC : entity work.sdlc_crc16_ccitt
|
U_RX_CRC : entity work.sdlc_crc16_ccitt
|
generic map(
|
generic map(
|
Poly_Init => Poly_Init,
|
Poly_Init => Poly_Init,
|
Reset_Level => Reset_Level
|
Reset_Level => Reset_Level
|
)
|
)
|
port map(
|
port map(
|
Clock => Clock,
|
Clock => Clock,
|
Reset => Reset,
|
Reset => Reset,
|
--
|
--
|
Clear => RX_CRC_Clr,
|
Clear => RX_Frame_Start,
|
Wr_Data => RX_Data,
|
Wr_En => RX_Frame_Valid,
|
Wr_En => RX_CRC_En,
|
Wr_Data => RX_Frame_Data,
|
|
--
|
|
CRC16_Valid => RX_CRC_Valid,
|
|
CRC16_Out => RX_CRC_Data
|
|
);
|
|
|
|
U_RX_FSM : entity work.sdlc_serial_rxfsm
|
|
generic map(
|
|
Reset_Level => Reset_Level
|
|
)
|
|
port map(
|
|
Clock => Clock,
|
|
Reset => Reset,
|
|
--
|
|
BClk_Okay => BClk_Okay,
|
|
--
|
|
DP_Port1_Addr => DP_Port1_Addr,
|
|
DP_Port1_RWn => DP_Port1_RWn,
|
|
DP_Port1_WrData => DP_Port1_WrData,
|
|
DP_Port1_RdData => DP_Port1_RdData,
|
|
DP_Port1_Req => DP_Port1_Req,
|
|
DP_Port1_Ack => DP_Port1_Ack,
|
|
--
|
|
RX_CRC_Valid => RX_CRC_Valid,
|
|
RX_CRC_Data => RX_CRC_Data,
|
|
--
|
|
RX_Frame_Start => RX_Frame_Start,
|
|
RX_Frame_Stop => RX_Frame_Stop,
|
|
RX_Frame_Valid => RX_Frame_Valid,
|
|
RX_Frame_Data => RX_Frame_Data,
|
--
|
--
|
CRC16_Out => RX_CRC_Data,
|
RX_Interrupt => RX_Interrupt
|
CRC16_Valid => RX_CRC_Valid
|
|
);
|
);
|
|
|
|
-- ***************************************************************************
|
|
-- * Merge Interrupts *
|
|
-- ***************************************************************************
|
|
|
|
Interrupt_merge_proc: process( Clock, Reset )
|
|
begin
|
|
if( Reset = Reset_Level )then
|
|
Interrupt <= '0';
|
|
elsif( rising_edge(Clock) )then
|
|
Interrupt <= RX_Interrupt or TX_Interrupt;
|
|
end if;
|
|
end process;
|
|
|
end architecture;
|
end architecture;
|
No newline at end of file
|
No newline at end of file
|