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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [misclib/] [tap_uart.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
--!
2
--! Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
3
--!
4
--! Licensed under the Apache License, Version 2.0 (the "License");
5
--! you may not use this file except in compliance with the License.
6
--! You may obtain a copy of the License at
7
--!
8
--!     http://www.apache.org/licenses/LICENSE-2.0
9
--! Unless required by applicable law or agreed to in writing, software
10
--! distributed under the License is distributed on an "AS IS" BASIS,
11
--! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
--! See the License for the specific language governing permissions and
13
--! limitations under the License.
14
--!
15
 
16
library ieee;
17
use ieee.std_logic_1164.all;
18
library commonlib;
19
use commonlib.types_common.all;
20
--! AMBA system bus specific library.
21
library ambalib;
22
--! AXI4 configuration constants.
23
use ambalib.types_amba4.all;
24
library misclib;
25
use misclib.types_misc.all;
26
 
27
entity uart_tap is
28
  port (
29
    nrst     : in std_logic;
30
    clk      : in std_logic;
31
    i_uart   : in  uart_in_type;
32
    o_uart   : out uart_out_type;
33
    i_msti   : in nasti_master_in_type;
34
    o_msto   : out nasti_master_out_type;
35
    o_mstcfg : out nasti_master_config_type
36
  );
37
end;
38
 
39
architecture arch_uart_tap of uart_tap is
40
 
41
  constant MAGIC_ID : std_logic_vector(7 downto 0) := X"31";
42
  constant SCALER_DEFAULT : std_logic_vector(17 downto 0) := "111111111111111011";
43
  constant BAUD_DEFAULT : std_logic_vector(17 downto 0) := (others => '1');
44
  constant HANDSHAKE_ACK : std_logic_vector(31 downto 0) := X"0a4b4341";
45
 
46
  constant xmstconfig : nasti_master_config_type := (
47
     descrsize => PNP_CFG_MASTER_DESCR_BYTES,
48
     descrtype => PNP_CFG_TYPE_MASTER,
49
     vid => VENDOR_GNSSSENSOR,
50
     did => GNSSSENSOR_UART_TAP
51
  );
52
 
53
  type uart_state_type is (idle, startbit, data, stopbit);
54
  type dma_req_state_type is (
55
      DMAREQ_IDLE,
56
      DMAREQ_OPERATION,
57
      DMAREQ_ADDR,
58
      DMAREQ_READ,
59
      DMAREQ_WAIT_READ_RESP,
60
      DMAREQ_UART_TX,
61
      DMAREQ_WDATA,
62
      DMAREQ_WRITE
63
   );
64
 
65
  type registers is record
66
    dma : dma_bank_type;
67
 
68
    tx_data   : std_logic_vector(31 downto 0);
69
    tx_byte_cnt : integer range 0 to 4;
70
 
71
    dma_req_state : dma_req_state_type;
72
    dma_state_next : dma_req_state_type;
73
    dma_req_write : std_logic;
74
    dma_byte_cnt : integer range 0 to 7;
75
    dma_req_len : integer range 0 to 63;
76
    dma_req_addr : std_logic_vector(63 downto 0);
77
    dma_req_wdata : std_logic_vector(31 downto 0);
78
    rword_valid : std_logic;
79
    rword : std_logic_vector(31 downto 0);
80
    watchdog : integer;
81
  end record;
82
 
83
  signal r, rin : registers;
84
  signal dma_response : dma_response_type;
85
 
86
  signal w_com_dready : std_logic;   -- new byte is avaiable for read
87
  signal w_com_accepted : std_logic; -- new byte can be accepted;
88
  signal wb_com_data : std_logic_vector(7 downto 0);
89
  signal w_com_thempty : std_logic; -- transmitter's hold register is empty
90
  signal w_com_write : std_logic;
91
 
92
  component dcom_uart is
93
  port (
94
    rst    : in  std_ulogic;
95
    clk    : in  std_ulogic;
96
    i_cfg_frame : in std_logic;
97
    i_cfg_ovf   : in std_logic;
98
    i_cfg_break : in std_logic;
99
    i_cfg_tcnt  : in std_logic_vector(1 downto 0);
100
    i_cfg_rxen  : in std_logic;
101
    i_cfg_brate : in std_logic_vector(17 downto 0);
102
    i_cfg_scaler : in std_logic_vector(17 downto 0);
103
    o_cfg_scaler : out std_logic_vector(31 downto 0);
104
    o_cfg_rxen : out std_logic;
105
    o_cfg_txen : out std_logic;
106
    o_cfg_flow : out std_logic;
107
 
108
    i_com_read          : in std_ulogic;
109
    i_com_write         : in std_ulogic;
110
    i_com_data          : in std_logic_vector(7 downto 0);
111
    o_com_dready        : out std_ulogic;
112
    o_com_tsempty       : out std_ulogic;
113
    o_com_thempty       : out std_ulogic;
114
    o_com_lock          : out std_ulogic;
115
    o_com_enable        : out std_ulogic;
116
    o_com_data          : out std_logic_vector(7 downto 0);
117
    ui     : in  uart_in_type;
118
    uo     : out uart_out_type
119
  );
120
  end component;
121
 
122
begin
123
 
124
  comblogic : process(nrst, i_msti, i_uart, r, dma_response, w_com_dready,
125
                      wb_com_data, w_com_thempty)
126
    variable v : registers;
127
    variable wb_dma_request : dma_request_type;
128
    variable wb_dma_response : dma_response_type;
129
    variable wb_msto : nasti_master_out_type;
130
 
131
    variable v_com_write : std_logic;
132
    variable v_com_accepted : std_logic;
133
  begin
134
 
135
    v := r;
136
    wb_dma_request.valid := '0';
137
    wb_dma_request.ready := '0';
138
    wb_dma_request.write := '0';
139
    wb_dma_request.addr := (others => '0');
140
    wb_dma_request.size := "010"; -- 4 bytes
141
    wb_dma_request.bytes := (others => '0');
142
    wb_dma_request.wdata := (others => '0');
143
 
144
    v_com_accepted := '0';
145
    v_com_write := '0';
146
 
147
    --! DMA control
148
    case r.dma_req_state is
149
    when DMAREQ_IDLE =>
150
        v_com_accepted := '1';
151
        if w_com_dready = '1' and wb_com_data = MAGIC_ID then
152
            v.dma_req_state := DMAREQ_OPERATION;
153
        end if;
154
    when DMAREQ_OPERATION =>
155
        v_com_accepted := '1';
156
        if w_com_dready = '1' then
157
            v.dma_req_write := wb_com_data(6);
158
            v.dma_req_len := conv_integer(wb_com_data(5 downto 0));
159
            v.dma_req_state := DMAREQ_ADDR;
160
            v.dma_byte_cnt := 0;
161
        end if;
162
    when DMAREQ_ADDR =>
163
        v_com_accepted := '1';
164
        if w_com_dready = '1' then
165
            v.dma_req_addr := wb_com_data & r.dma_req_addr(63 downto 8);
166
            if r.dma_byte_cnt = 7 then
167
                if (wb_com_data & r.dma_req_addr(63 downto 40)) /= X"00000000" then
168
                    v.dma_req_state := DMAREQ_IDLE;
169
                elsif r.dma_req_write = '1' then
170
                    v.dma_req_state := DMAREQ_WDATA;
171
                    v.dma_byte_cnt := 0;
172
                else
173
                    v.dma_req_state := DMAREQ_READ;
174
                end if;
175
            else
176
                v.dma_byte_cnt := r.dma_byte_cnt + 1;
177
            end if;
178
        end if;
179
    when DMAREQ_READ =>
180
        wb_dma_request.valid := '1';
181
        wb_dma_request.write := '0';
182
        wb_dma_request.addr := r.dma_req_addr(CFG_NASTI_ADDR_BITS-1 downto 0);
183
        wb_dma_request.bytes := conv_std_logic_vector(4, 11);
184
        wb_dma_request.wdata := (others => '0');
185
        if dma_response.ready = '1' then
186
            v.dma_req_state := DMAREQ_WAIT_READ_RESP;
187
        end if;
188
    when DMAREQ_WAIT_READ_RESP =>
189
        wb_dma_request.ready := '1';
190
        if dma_response.valid = '1' then
191
            v.dma_req_state := DMAREQ_UART_TX;
192
            v.tx_data := dma_response.rdata(31 downto 0);
193
            v.tx_byte_cnt := 4;
194
            if r.dma_req_len = 0 then
195
                v.dma_state_next := DMAREQ_IDLE;
196
            else
197
                v.dma_req_len := r.dma_req_len - 1;
198
                v.dma_req_addr := r.dma_req_addr + 4;
199
                v.dma_state_next := DMAREQ_READ;
200
            end if;
201
        end if;
202
 
203
    when DMAREQ_WDATA =>
204
        v_com_accepted := '1';
205
        if w_com_dready = '1' then
206
            v.dma_req_wdata := wb_com_data & r.dma_req_wdata(31 downto 8);
207
            v.dma_byte_cnt := r.dma_byte_cnt + 1;
208
            if r.dma_byte_cnt = 3 then
209
               v.dma_req_state := DMAREQ_WRITE;
210
            end if;
211
        end if;
212
    when DMAREQ_WRITE =>
213
        wb_dma_request.valid := '1';
214
        wb_dma_request.write := '1';
215
        wb_dma_request.addr := r.dma_req_addr(CFG_NASTI_ADDR_BITS-1 downto 0);
216
        wb_dma_request.bytes := conv_std_logic_vector(4, 11);
217
        wb_dma_request.wdata := r.dma_req_wdata & r.dma_req_wdata;
218
        if dma_response.ready = '1' then
219
            if r.dma_req_len = 0 then
220
                v.dma_req_state := DMAREQ_UART_TX; -- Handshake ACK
221
                v.tx_data := HANDSHAKE_ACK;
222
                v.tx_byte_cnt := 4;
223
                v.dma_state_next := DMAREQ_IDLE;
224
            else
225
                v.dma_byte_cnt := 0;
226
                v.dma_req_len := r.dma_req_len - 1;
227
                v.dma_req_addr := r.dma_req_addr + 4;
228
                v.dma_req_state := DMAREQ_WDATA;
229
            end if;
230
        end if;
231
 
232
    when DMAREQ_UART_TX =>
233
        v_com_write := '1';
234
        if r.tx_byte_cnt = 0 then
235
            v.dma_req_state := r.dma_state_next;
236
        elsif w_com_thempty = '1' then
237
            v.tx_byte_cnt := r.tx_byte_cnt - 1;
238
            v.tx_data := X"00" & r.tx_data(31 downto 8);
239
        end if;
240
    when others =>
241
    end case;
242
 
243
 
244
    procedureAxi4DMA(
245
        i_request => wb_dma_request,
246
        o_response => wb_dma_response,
247
        i_bank => r.dma,
248
        o_bank => v.dma,
249
        i_msti => i_msti,
250
        o_msto => wb_msto
251
    );
252
    dma_response <= wb_dma_response;
253
    w_com_accepted <= v_com_accepted;
254
    w_com_write <= v_com_write;
255
 
256
 
257
    if nrst = '0' then
258
        v.tx_byte_cnt := 0;
259
        v.tx_data := (others => '0');
260
 
261
        v.dma := DMA_BANK_RESET;
262
        v.dma_req_state := DMAREQ_IDLE;
263
        v.dma_state_next := DMAREQ_IDLE;
264
        v.dma_req_write := '0';
265
        v.dma_byte_cnt := 0;
266
        v.dma_req_len := 0;
267
        v.dma_req_addr := (others => '0');
268
        v.dma_req_wdata := (others => '0');
269
    end if;
270
 
271
    rin <= v;
272
    o_msto <= wb_msto;
273
  end process;
274
 
275
  o_mstcfg <= xmstconfig;
276
 
277
  dcom0 : dcom_uart  port map (
278
    rst    => nrst,
279
    clk    => clk,
280
    i_cfg_frame => '0',
281
    i_cfg_ovf   => '0',
282
    i_cfg_break => '0',
283
    i_cfg_tcnt  => "00",
284
    i_cfg_rxen  => '0',
285
    i_cfg_brate => BAUD_DEFAULT,
286
    i_cfg_scaler => SCALER_DEFAULT,
287
    o_cfg_scaler => open,
288
    o_cfg_rxen => open,
289
    o_cfg_txen => open,
290
    o_cfg_flow => open,
291
 
292
    i_com_read => w_com_accepted,
293
    i_com_write => w_com_write,
294
    i_com_data  => r.tx_data(7 downto 0),
295
    o_com_dready => w_com_dready,
296
    o_com_tsempty => open,
297
    o_com_thempty => w_com_thempty,
298
    o_com_lock => open,
299
    o_com_enable => open,
300
    o_com_data => wb_com_data,
301
    ui => i_uart,
302
    uo => o_uart
303
  );
304
 
305
 
306
  -- registers:
307
  regs : process(clk)
308
  begin
309
     if rising_edge(clk) then
310
        r <= rin;
311
     end if;
312
  end process;
313
 
314
end;

powered by: WebSVN 2.1.0

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