URL
https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk
Subversion Repositories open8_urisc
[/] [open8_urisc/] [trunk/] [VHDL/] [o8_sdlc_if.vhd] - Rev 194
Go to most recent revision | Compare with Previous | Blame | View Log
-- Copyright (c)2020 Jeremy Seth Henry -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without -- modification, are permitted provided that the following conditions are met: -- * Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- * Redistributions in binary form must reproduce the above copyright -- notice, this list of conditions and the following disclaimer in the -- documentation and/or other materials provided with the distribution, -- where applicable (as part of a user interface, debugging port, etc.) -- -- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY -- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY -- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -- 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 -- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- -- VHDL Units : o8_sdlc_if -- Description: Provides a full memory-mapped SDLC stack with automatic CRC16 -- Checksum insertion and integrity checking. -- -- Transmit Memory Map -- "0_0000_0000" (0x000) TX Buffer START -- "0_1111_1101" (0x0FD) TX Buffer END -- "0_1111_1110" (0x0FE) Clock Status* -- "0_1111_1111" (0x0FF) TX Length / Status** -- -- Receive Memory Map -- "1_0000_0000" (0x100) RX Buffer START -- "1_1111_1110" (0x1FE) RX Buffer END -- "1_1111_1111" (0x1FF) RX Length / Status -- -- * Address 0xFE reports the SDLC bit clock status and updates on changes. If -- the bit clock goes away (BClk_Okay = '0'), the field will report 0x00. -- otherwise it will report 0xFF. Note that the CPU can overwrite this -- location, at which point the status will be invalid. -- -- ** This location serves as the control/status register for the interface -- 1) Writing 0x00 will reset the clock status flag in 0xFE without -- triggering an interrupt. -- 2) Writing a value between 1 and 253 will trigger the transmit engine, -- using the write value as the packet length. -- 3) Writing 0xFE or 0xFF will be ignored by the engine. -- 4) This value will change from the user written value to 0xFF once the -- packet is transmitted. -- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; library work; use work.open8_pkg.all; library work; use work.sdlc_serial_pkg.all; entity o8_sdlc_if is generic( Poly_Init : std_logic_vector(15 downto 0) := x"0000"; Set_As_Master : boolean := true; Clock_Offset : integer := 6; BitClock_Freq : real := 500000.0; Sys_Freq : real := 100000000.0; Reset_Level : std_logic := '1'; Address : ADDRESS_TYPE ); port( Clock : in std_logic; Reset : in std_logic; -- Bus_Address : in ADDRESS_TYPE; Wr_Enable : in std_logic; Wr_Data : in DATA_TYPE; Rd_Enable : in std_logic; Rd_Data : out DATA_TYPE; Interrupt : out std_logic; -- Serial IO SDLC_In : in std_logic; SDLC_SClk : in std_logic; SDLC_MClk : out std_logic; SDLC_Out : out std_logic ); end entity; architecture behave of o8_sdlc_if is -- Connect the CPU to the dual-port memory constant Base_Addr : std_logic_vector(15 downto 9) := Address(15 downto 9); alias RAM_Upper_Addr is Bus_Address(15 downto 9); alias RAM_Lower_Addr is Bus_Address(8 downto 0); signal RAM_Addr_Match : std_logic := '0'; signal RAM_Wr_En : std_logic := '0'; signal RAM_Rd_En : std_logic := '0'; signal Rd_Data_i : DATA_TYPE := OPEN8_NULLBUS; constant Reg_Sub_Addr : std_logic_vector(8 downto 0) := conv_std_logic_vector(255,9); signal Reg_Addr : std_logic_vector(8 downto 0) := (others => '0'); signal Reg_Wr_En : std_logic := '0'; signal Reg_Updated : 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_Wr_Data : DATA_IN_TYPE := x"00"; signal DP_Wr_En : std_logic := '0'; signal DP_Rd_Data : DATA_IN_TYPE := x"00"; signal BClk_RE : std_logic := '0'; signal BClk_FE : std_logic := '0'; signal TX_Wr_En : std_logic := '0'; signal TX_Wr_Flag : std_logic := '0'; signal TX_Wr_Data : DATA_IN_TYPE := x"00"; signal TX_Req_Next : std_logic := '0'; signal TX_CRC_Clr : std_logic := '0'; signal TX_CRC_En : std_logic := '0'; 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 RX_Valid : std_logic := '0'; signal RX_Flag : std_logic := '0'; signal RX_Data : DATA_IN_TYPE := x"00"; signal RX_Idle : std_logic := '0'; signal RX_CRC_Clr : std_logic := '0'; signal RX_CRC_En : std_logic := '0'; signal RX_CRC_Data : CRC_OUT_TYPE := x"0000"; signal RX_CRC_Valid : std_logic := '0'; signal BClk_Okay : std_logic := '0'; begin -- This decode needs to happen immediately, to give the RAM a chance to -- do the lookup before we have to set Rd_Data RAM_Addr_Match <= '1' when Base_Addr = RAM_Upper_Addr else '0'; RAM_Wr_En <= RAM_Addr_Match and Wr_Enable; CPU_RAM_proc: process( Reset, Clock ) begin if( Reset = Reset_Level )then Reg_Addr <= (others => '0'); Reg_Wr_En <= '0'; Reg_Updated <= '0'; RAM_Rd_En <= '0'; Rd_Data <= OPEN8_NULLBUS; elsif( rising_edge(Clock) )then Reg_Addr <= RAM_Lower_Addr; Reg_Wr_En <= RAM_Addr_Match and Wr_Enable; Reg_Updated <= '0'; if( Reg_Addr = Reg_Sub_Addr )then Reg_Updated <= Reg_Wr_En; end if; RAM_Rd_En <= RAM_Addr_Match and Rd_Enable; Rd_Data <= OPEN8_NULLBUS; if( RAM_Rd_En = '1' )then Rd_Data <= Rd_Data_i; end if; end if; end process; U_RAM : entity work.ram_dp512b_core port map( clock => Clock, address_a => RAM_Lower_Addr, address_b => DP_Addr, data_a => Wr_Data, data_b => DP_Wr_Data, wren_a => RAM_Wr_En, wren_b => DP_Wr_En, q_a => Rd_Data_i, q_b => DP_Rd_Data ); U_BCLK : entity work.sdlc_serial_clk generic map( Set_As_Master => Set_As_Master, BitClock_Freq => BitClock_Freq, Reset_Level => Reset_Level, Sys_Freq => Sys_Freq ) port map( Clock => Clock, Reset => Reset, -- BClk_In => SDLC_SClk, BClk_Out => SDLC_MClk, BClk_FE => BClk_FE, BClk_RE => BClk_RE, BClk_Okay => BClk_Okay ); U_CTRL : entity work.sdlc_serial_ctrl generic map( Reset_Level => Reset_Level ) port map( Clock => Clock, Reset => Reset, -- BClk_Okay => BClk_Okay, -- Reg_Updated => Reg_Updated, -- DP_Addr => DP_Addr, DP_Wr_Data => DP_Wr_Data, DP_Wr_En => DP_Wr_En, DP_Rd_Data => DP_Rd_Data, -- TX_Wr_En => TX_Wr_En, TX_Wr_Flag => TX_Wr_Flag, TX_Wr_Data => TX_Wr_Data, TX_Req_Next => TX_Req_Next, -- TX_CRC_Clr => TX_CRC_Clr, TX_CRC_En => TX_CRC_En, TX_CRC_Data => TX_CRC_Data, TX_CRC_Valid => TX_CRC_Valid, -- RX_Valid => RX_Valid, RX_Flag => RX_Flag, RX_Data => RX_Data, RX_Idle => RX_Idle, -- RX_CRC_Clr => RX_CRC_Clr, RX_CRC_En => RX_CRC_En, RX_CRC_Data => RX_CRC_Data, RX_CRC_Valid => RX_CRC_Valid, -- Interrupt => Interrupt ); U_TX_SER : entity work.sdlc_serial_tx generic map( Reset_Level => Reset_Level ) port map( Clock => Clock, Reset => Reset, -- BClk_FE => BClk_FE, BClk_RE => BClk_RE, BClk_Okay => BClk_Okay, -- TX_En => TX_Wr_En, TX_FSS_Flag => TX_Wr_Flag, TX_Data => TX_Wr_Data, TX_Req_Next => TX_Req_Next, -- Serial_Out => SDLC_Out ); U_TX_CRC : entity work.sdlc_crc16_ccitt generic map( 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 generic map( Set_As_Master => Set_As_Master, Clock_Offset => Clock_Offset, Reset_Level => Reset_Level ) port map( Clock => Clock, Reset => Reset, -- BClk_RE => BClk_RE, BClk_Okay => BClk_Okay, -- Serial_In => SDLC_In, -- RX_Valid => RX_Valid, RX_Flag => RX_Flag, RX_Data => RX_Data, RX_Idle => RX_Idle ); U_RX_CRC : entity work.sdlc_crc16_ccitt generic map( Poly_Init => Poly_Init, Reset_Level => Reset_Level ) port map( Clock => Clock, Reset => Reset, -- Clear => RX_CRC_Clr, Wr_Data => RX_Data, Wr_En => RX_CRC_En, -- CRC16_Out => RX_CRC_Data, CRC16_Valid => RX_CRC_Valid ); end architecture;
Go to most recent revision | Compare with Previous | Blame | View Log