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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [work/] [tb/] [uart_sim.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
------------------------------------------------------------------------------
2
--! @file
3
--! @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
--! @author    Sergey Khabarov - sergeykhbr@gmail.com
5
------------------------------------------------------------------------------
6
 
7
library ieee;
8
use ieee.std_logic_1164.all;
9
library std;
10
use std.textio.all;
11
library commonlib;
12
use commonlib.types_common.all;
13
use commonlib.types_util.all;
14
 
15
entity uart_sim is
16
  generic (
17
    clock_rate : integer := 10;
18
    binary_bytes_max : integer := 8;
19
    use_binary : boolean := false
20
  );
21
  port (
22
    rst : in std_logic;
23
    clk : in std_logic;
24
    wr_str : in std_logic;
25
    instr : in string;
26
    bin_data : in std_logic_vector(8*binary_bytes_max-1 downto 0);
27
    bin_bytes_sz : in integer;
28
    td  : in std_logic;
29
    rtsn : in std_logic;
30
    rd  : out std_logic;
31
    ctsn : out std_logic;
32
    busy : out std_logic
33
  );
34
end;
35
 
36
architecture uart_sim_rtl of uart_sim is
37
 
38
  constant STATE_idle : integer := 0;
39
  constant STATE_startbit : integer := 1;
40
  constant STATE_data : integer := 2;
41
  constant STATE_parity : integer := 3;
42
  constant STATE_stopbit : integer := 4;
43
 
44
  type registers is record
45
      txstate : integer range 0 to 4;
46
      tx_data : std_logic_vector(10 downto 0);
47
      txbitcnt : integer range 0 to 12;
48
      clk_rate_cnt : integer;
49
      msg_symb_cnt : integer range 0 to 256;
50
      msg_len : integer;
51
      msg : string(1 to 256);
52
      msg_bin : std_logic_vector(8*binary_bytes_max-1 downto 0);
53
      is_data : std_logic;
54
  end record;
55
 
56
  signal r, rin : registers;
57
 
58
begin
59
 
60
  comblogic : process(rst, r, wr_str, instr)
61
    variable v : registers;
62
    variable symbol : std_logic_vector(7 downto 0);
63
    variable RATE_EVENT : std_logic;
64
  begin
65
     v := r;
66
     RATE_EVENT := '0';
67
     if r.clk_rate_cnt = (clock_rate - 1) then
68
         RATE_EVENT := '1';
69
     end if;
70
 
71
     if wr_str = '1' then
72
        if use_binary = true then
73
            v.msg_bin := bin_data;
74
            v.msg_len := bin_bytes_sz;
75
        else
76
            v.msg := instr;
77
            v.msg_len := strlen(instr);
78
        end if;
79
        v.is_data := '1';
80
     end if;
81
 
82
     case r.txstate is
83
     when STATE_idle =>
84
        v.txbitcnt := 0;
85
        if r.is_data = '1' and RATE_EVENT = '1' then
86
           v.txstate := STATE_startbit;
87
           v.is_data := '0';
88
           if use_binary = true then
89
               symbol := r.msg_bin(8*binary_bytes_max-1 downto 8*binary_bytes_max-8);
90
               v.msg_bin := r.msg_bin(8*(binary_bytes_max-1)-1 downto 0) & X"00";
91
           else
92
               symbol := SymbolToSVector(r.msg, r.msg_symb_cnt);
93
           end if;
94
           v.tx_data := "01" & symbol & '0'; -- [stopbit=1, ?parity? (skiped), data, start_bit=0]
95
        elsif r.is_data = '1' then
96
          -- do nothing
97
        else
98
          v.tx_data := (others => '1');
99
          v.msg_symb_cnt := 0;     -- symbols in string start from 1 to len.
100
          v.clk_rate_cnt := 0;
101
        end if;
102
 
103
     when STATE_startbit =>
104
        if RATE_EVENT = '1' then
105
            v.txstate := STATE_data;
106
            v.tx_data := '0' & r.tx_data(10 downto 1);
107
        end if;
108
 
109
     when STATE_data =>
110
        if RATE_EVENT = '1' then
111
            v.tx_data := '0' & r.tx_data(10 downto 1);
112
            if r.txbitcnt = 8 then
113
                v.txstate := STATE_stopbit;
114
            end if;
115
        end if;
116
 
117
     when STATE_parity =>
118
         v.tx_data := '0' & r.tx_data(10 downto 1);
119
 
120
     when STATE_stopbit =>
121
        if RATE_EVENT = '1' then
122
            v.tx_data := (others => '1');
123
            if (r.msg_symb_cnt + 1) = r.msg_len then
124
                v.txstate := STATE_idle;
125
            else
126
                v.is_data := '1';
127
                v.txstate := STATE_idle;
128
                v.msg_symb_cnt := r.msg_symb_cnt + 1;
129
            end if;
130
        end if;
131
     when others =>
132
     end case;
133
 
134
     if r.txstate /= STATE_idle and RATE_EVENT = '1' then
135
         busy <= '1';
136
         v.txbitcnt := r.txbitcnt + 1;
137
     else
138
         busy <= '0';
139
     end if;
140
 
141
     if RATE_EVENT = '1' then
142
       v.clk_rate_cnt := 0;
143
     else
144
       v.clk_rate_cnt := r.clk_rate_cnt + 1;
145
     end if;
146
 
147
     -- Reset
148
     if rst = '1' then
149
        v.txstate := STATE_idle;
150
        v.clk_rate_cnt := 0;
151
        v.is_data := '0';
152
     end if;
153
 
154
     ctsn <= rst;
155
     rd <= r.tx_data(0);
156
     rin <= v;
157
   end process;
158
 
159
 
160
  procCheck : process (clk)
161
  begin
162
    if rising_edge(clk) then
163
        r <= rin;
164
    end if;
165
  end process;
166
 
167
end;

powered by: WebSVN 2.1.0

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