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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [VHDL/] [o8_sdlc_if.vhd] - Blame information for rev 200

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 192 jshamlet
-- Copyright (c)2020 Jeremy Seth Henry
2
-- All rights reserved.
3
--
4
-- Redistribution and use in source and binary forms, with or without
5
-- modification, are permitted provided that the following conditions are met:
6
--     * Redistributions of source code must retain the above copyright
7
--       notice, this list of conditions and the following disclaimer.
8
--     * Redistributions in binary form must reproduce the above copyright
9
--       notice, this list of conditions and the following disclaimer in the
10
--       documentation and/or other materials provided with the distribution,
11
--       where applicable (as part of a user interface, debugging port, etc.)
12
--
13
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
14
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
17
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
--
24
-- VHDL Units :  o8_sdlc_if
25
-- Description:  Provides a full memory-mapped SDLC stack with automatic CRC16
26
--                Checksum insertion and integrity checking.
27
--
28
-- Transmit Memory Map
29
-- "0_0000_0000" (0x000) TX Buffer START
30
-- "0_1111_1101" (0x0FD) TX Buffer END
31
-- "0_1111_1110" (0x0FE) Clock Status*
32
-- "0_1111_1111" (0x0FF) TX Length / Status**
33
--
34
-- Receive Memory Map
35
-- "1_0000_0000" (0x100) RX Buffer START
36 196 jshamlet
-- "1_1111_1101" (0x1FD) RX Buffer END
37
-- "1_1111_1110" (0x0FE) Reserved
38
-- "1_1111_1111" (0x1FF) RX Length / Status***
39 192 jshamlet
--
40 199 jshamlet
-- *   Address 0xFE reports the SDLC bit clock status and updates on changes.
41 196 jshamlet
--     1) If BClk_Okay = '0' (Bitclock is NOT present), the field will report
42
--         0x00. Otherwise, it will report 0xFF if the bitclock is present.
43
--     2) Writing any value to the register will cause the controller to
44
--        silently reset the clock status without causing an interrupt.
45 199 jshamlet
--
46 196 jshamlet
-- **  This location serves as the control/status register for transmit
47
--     1) Writing a value between 1 and 253 will trigger the transmit engine,
48
--         using the write value as the packet length.
49
--     2) Values 0x00, 0xFE, or 0xFF are invalid, and will be ignored.
50
--     3) This value will change from the user written value to 0xFF once the
51
--         packet is transmitted to indicate the transmission is complete.
52 199 jshamlet
--
53 196 jshamlet
-- *** This location serves as the status register for the receive
54
--     1) This value is only updated on reception of a full frame, indicated
55
--         by a start followed by a stop flag. Incomplete frames are ignored.
56
--     2) If the packet CRC matches the transmitted CRC, the packet is
57
--         considered valid, and the received length (less CRC) is written.
58
--     3) If the packet CRC doesn't match, a value of ERR_CHECKSUM is written.
59
--     4) If too many bytes are received (buffer overflow), a value of
60
--         ERR_LENGTH is written.
61 192 jshamlet
 
62
library ieee;
63
  use ieee.std_logic_1164.all;
64
  use ieee.std_logic_unsigned.all;
65
  use ieee.std_logic_arith.all;
66
 
67
library work;
68
  use work.open8_pkg.all;
69
 
70
library work;
71
  use work.sdlc_serial_pkg.all;
72
 
73
entity o8_sdlc_if is
74
generic(
75 199 jshamlet
  Monitor_Enable             : boolean := true;
76
  Attach_Monitor_to_CPU_Side : boolean := false;
77 192 jshamlet
  Poly_Init                  : std_logic_vector(15 downto 0) := x"0000";
78
  Set_As_Master              : boolean := true;
79
  Clock_Offset               : integer := 6;
80
  BitClock_Freq              : real := 500000.0;
81
  Sys_Freq                   : real := 100000000.0;
82
  Reset_Level                : std_logic := '1';
83
  Address                    : ADDRESS_TYPE
84
);
85
port(
86
  Clock                      : in  std_logic;
87
  Reset                      : in  std_logic;
88
  --
89
  Bus_Address                : in  ADDRESS_TYPE;
90
  Wr_Enable                  : in  std_logic;
91
  Wr_Data                    : in  DATA_TYPE;
92
  Rd_Enable                  : in  std_logic;
93
  Rd_Data                    : out DATA_TYPE;
94
  Interrupt                  : out std_logic;
95
  -- Serial IO
96
  SDLC_In                    : in  std_logic;
97
  SDLC_SClk                  : in  std_logic;
98
  SDLC_MClk                  : out std_logic;
99
  SDLC_Out                   : out std_logic
100
);
101
end entity;
102
 
103
architecture behave of o8_sdlc_if is
104
 
105
  -- Connect the CPU to the dual-port memory
106
  constant Base_Addr         : std_logic_vector(15 downto 9)
107
                               := Address(15 downto 9);
108
 
109
  alias RAM_Upper_Addr       is Bus_Address(15 downto 9);
110
  alias RAM_Lower_Addr       is Bus_Address(8 downto 0);
111
 
112
  signal RAM_Addr_Match      : std_logic := '0';
113
  signal RAM_Wr_En           : std_logic := '0';
114
  signal RAM_Rd_En           : std_logic := '0';
115
  signal Rd_Data_i           : DATA_TYPE := OPEN8_NULLBUS;
116
 
117 196 jshamlet
  constant Reg_Sub_Addr      : std_logic_vector(8 downto 1) := x"7F";
118 192 jshamlet
 
119 196 jshamlet
  alias Reg_Upper_Addr       is Bus_Address(8 downto 1);
120
  alias Reg_Lower_Addr       is Bus_Address(0);
121
 
122
  signal Reg_Addr            : std_logic_vector(8 downto 1) := (others => '0');
123
  signal Reg_Sel             : std_logic := '0';
124 192 jshamlet
  signal Reg_Wr_En           : std_logic := '0';
125 196 jshamlet
  signal Reg_Clk_Sel         : std_logic := '0';
126
  signal Reg_TxS_Sel         : std_logic := '0';
127
 
128 192 jshamlet
  -- Connect the serial engine to the dual-port memory
129
  signal DP_Addr             : std_logic_vector(8 downto 0) := (others => '0');
130
  signal DP_Wr_Data          : DATA_IN_TYPE := x"00";
131
  signal DP_Wr_En            : std_logic := '0';
132
  signal DP_Rd_Data          : DATA_IN_TYPE := x"00";
133
 
134
  signal BClk_RE             : std_logic := '0';
135
  signal BClk_FE             : std_logic := '0';
136
 
137
  signal TX_Wr_En            : std_logic := '0';
138
  signal TX_Wr_Flag          : std_logic := '0';
139
  signal TX_Wr_Data          : DATA_IN_TYPE := x"00";
140
  signal TX_Req_Next         : std_logic := '0';
141
 
142
  signal TX_CRC_Clr          : std_logic := '0';
143
  signal TX_CRC_En           : std_logic := '0';
144
  signal TX_CRC_Data         : CRC_OUT_TYPE := x"0000";
145
  alias  TX_CRC_Data_LB      is TX_CRC_Data(7 downto 0);
146
  alias  TX_CRC_Data_UB      is TX_CRC_Data(15 downto 8);
147
  signal TX_CRC_Valid        : std_logic := '0';
148
 
149
  signal RX_Valid            : std_logic := '0';
150
  signal RX_Flag             : std_logic := '0';
151
  signal RX_Data             : DATA_IN_TYPE := x"00";
152
  signal RX_Idle             : std_logic := '0';
153
 
154
  signal RX_CRC_Clr          : std_logic := '0';
155
  signal RX_CRC_En           : std_logic := '0';
156
  signal RX_CRC_Data         : CRC_OUT_TYPE := x"0000";
157
  signal RX_CRC_Valid        : std_logic := '0';
158
 
159
  signal BClk_Okay           : std_logic := '0';
160
 
161
begin
162
 
163
  -- This decode needs to happen immediately, to give the RAM a chance to
164
  --  do the lookup before we have to set Rd_Data
165
  RAM_Addr_Match             <= '1' when Base_Addr = RAM_Upper_Addr else '0';
166
  RAM_Wr_En                  <= RAM_Addr_Match and Wr_Enable;
167
 
168
  CPU_RAM_proc: process( Reset, Clock )
169
  begin
170
    if( Reset = Reset_Level )then
171
      Reg_Addr               <= (others => '0');
172
      Reg_Wr_En              <= '0';
173 196 jshamlet
      Reg_Clk_Sel            <= '0';
174
      Reg_TxS_Sel            <= '0';
175 192 jshamlet
      RAM_Rd_En              <= '0';
176
      Rd_Data                <= OPEN8_NULLBUS;
177
    elsif( rising_edge(Clock) )then
178 196 jshamlet
      Reg_Addr               <= Reg_Upper_Addr;
179
      Reg_Sel                <= Reg_Lower_Addr;
180 192 jshamlet
      Reg_Wr_En              <= RAM_Addr_Match and Wr_Enable;
181
 
182 196 jshamlet
      Reg_Clk_Sel            <= '0';
183
      Reg_TxS_Sel            <= '0';
184 192 jshamlet
      if( Reg_Addr = Reg_Sub_Addr )then
185 196 jshamlet
        Reg_Clk_Sel          <= Reg_Wr_En and not Reg_Sel;
186
        Reg_TxS_Sel          <= Reg_Wr_En and Reg_Sel;
187 192 jshamlet
      end if;
188
 
189
      RAM_Rd_En              <= RAM_Addr_Match and Rd_Enable;
190
      Rd_Data                <= OPEN8_NULLBUS;
191
      if( RAM_Rd_En = '1' )then
192
        Rd_Data              <= Rd_Data_i;
193
      end if;
194
    end if;
195
  end process;
196
 
197 200 jshamlet
  U_RAM : entity work.sdlc_dp512b_ram
198 192 jshamlet
  port map(
199
    clock                    => Clock,
200
    address_a                => RAM_Lower_Addr,
201
    address_b                => DP_Addr,
202
    data_a                   => Wr_Data,
203
    data_b                   => DP_Wr_Data,
204
    wren_a                   => RAM_Wr_En,
205
    wren_b                   => DP_Wr_En,
206
    q_a                      => Rd_Data_i,
207
    q_b                      => DP_Rd_Data
208
  );
209
 
210 199 jshamlet
Attach_to_CPU_side: if( Monitor_Enable and Attach_Monitor_to_CPU_Side )generate
211
 
212
  U_MON: entity work.sdlc_monitor
213
  port map(
214
    clock                    => Clock,
215
    address                  => RAM_Lower_Addr,
216
    data                     => Wr_Data,
217
    wren                     => RAM_Wr_En,
218
    q                        => open
219
  );
220
end generate;
221
 
222
Attach_to_Int_side: if( Monitor_Enable and not Attach_Monitor_to_CPU_Side )generate
223
 
224
  U_MON: entity work.sdlc_monitor
225
  port map(
226
    clock                    => Clock,
227
    address                  => DP_Addr,
228
    data                     => DP_Wr_Data,
229
    wren                     => DP_Wr_En,
230
    q                        => open
231
  );
232
 
233
end generate;
234
 
235 192 jshamlet
  U_BCLK : entity work.sdlc_serial_clk
236
  generic map(
237
    Set_As_Master            => Set_As_Master,
238
    BitClock_Freq            => BitClock_Freq,
239
    Reset_Level              => Reset_Level,
240
    Sys_Freq                 => Sys_Freq
241
  )
242
  port map(
243
    Clock                    => Clock,
244
    Reset                    => Reset,
245
    --
246
    BClk_In                  => SDLC_SClk,
247
    BClk_Out                 => SDLC_MClk,
248
    BClk_FE                  => BClk_FE,
249
    BClk_RE                  => BClk_RE,
250
    BClk_Okay                => BClk_Okay
251
  );
252
 
253
  U_CTRL : entity work.sdlc_serial_ctrl
254
  generic map(
255
    Reset_Level              => Reset_Level
256
  )
257
  port map(
258
    Clock                    => Clock,
259
    Reset                    => Reset,
260
    --
261
    BClk_Okay                => BClk_Okay,
262
    --
263 196 jshamlet
    Reg_Clk_Sel              => Reg_Clk_Sel,
264
    Reg_TxS_Sel              => Reg_TxS_Sel,
265 192 jshamlet
    --
266
    DP_Addr                  => DP_Addr,
267
    DP_Wr_Data               => DP_Wr_Data,
268
    DP_Wr_En                 => DP_Wr_En,
269
    DP_Rd_Data               => DP_Rd_Data,
270
    --
271
    TX_Wr_En                 => TX_Wr_En,
272
    TX_Wr_Flag               => TX_Wr_Flag,
273
    TX_Wr_Data               => TX_Wr_Data,
274
    TX_Req_Next              => TX_Req_Next,
275
    --
276
    TX_CRC_Clr               => TX_CRC_Clr,
277
    TX_CRC_En                => TX_CRC_En,
278
    TX_CRC_Data              => TX_CRC_Data,
279
    TX_CRC_Valid             => TX_CRC_Valid,
280
    --
281
    RX_Valid                 => RX_Valid,
282
    RX_Flag                  => RX_Flag,
283
    RX_Data                  => RX_Data,
284
    RX_Idle                  => RX_Idle,
285
    --
286
    RX_CRC_Clr               => RX_CRC_Clr,
287
    RX_CRC_En                => RX_CRC_En,
288
    RX_CRC_Data              => RX_CRC_Data,
289
    RX_CRC_Valid             => RX_CRC_Valid,
290
    --
291
    Interrupt                => Interrupt
292
  );
293
 
294
  U_TX_SER : entity work.sdlc_serial_tx
295
  generic map(
296
    Reset_Level              => Reset_Level
297
  )
298
  port map(
299
    Clock                    => Clock,
300
    Reset                    => Reset,
301
    --
302
    BClk_FE                  => BClk_FE,
303
    BClk_RE                  => BClk_RE,
304
    BClk_Okay                => BClk_Okay,
305
    --
306
    TX_En                    => TX_Wr_En,
307
    TX_FSS_Flag              => TX_Wr_Flag,
308
    TX_Data                  => TX_Wr_Data,
309
    TX_Req_Next              => TX_Req_Next,
310
    --
311
    Serial_Out               => SDLC_Out
312
  );
313
 
314
  U_TX_CRC : entity work.sdlc_crc16_ccitt
315
  generic map(
316
    Poly_Init                => Poly_Init,
317
    Reset_Level              => Reset_Level
318
  )
319
  port map(
320
    Clock                    => Clock,
321
    Reset                    => Reset,
322
    --
323
    Clear                    => TX_CRC_Clr,
324
    Wr_Data                  => TX_Wr_Data,
325
    Wr_En                    => TX_CRC_En,
326
    --
327
    CRC16_Out                => TX_CRC_Data,
328
    CRC16_Valid              => TX_CRC_Valid
329
  );
330
 
331
  U_RX_SER : entity work.sdlc_serial_rx
332
  generic map(
333
    Set_As_Master            => Set_As_Master,
334
    Clock_Offset             => Clock_Offset,
335
    Reset_Level              => Reset_Level
336
  )
337
  port map(
338
    Clock                    => Clock,
339
    Reset                    => Reset,
340
    --
341
    BClk_RE                  => BClk_RE,
342
    BClk_Okay                => BClk_Okay,
343
    --
344
    Serial_In                => SDLC_In,
345
    --
346
    RX_Valid                 => RX_Valid,
347
    RX_Flag                  => RX_Flag,
348
    RX_Data                  => RX_Data,
349
    RX_Idle                  => RX_Idle
350
  );
351
 
352
  U_RX_CRC : entity work.sdlc_crc16_ccitt
353
  generic map(
354
    Poly_Init                => Poly_Init,
355
    Reset_Level              => Reset_Level
356
  )
357
  port map(
358
    Clock                    => Clock,
359
    Reset                    => Reset,
360
    --
361
    Clear                    => RX_CRC_Clr,
362
    Wr_Data                  => RX_Data,
363
    Wr_En                    => RX_CRC_En,
364
    --
365
    CRC16_Out                => RX_CRC_Data,
366
    CRC16_Valid              => RX_CRC_Valid
367
  );
368
 
369
end architecture;

powered by: WebSVN 2.1.0

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